0
class MyNetPack {
    Long count;

    public MyNetPack() {
        count = Long.valueOf(0);
    }

    public void reinit(Long count) {
        this.count = count;
    }

    public void process() {
        /* Some calculation */
    }
}

public class MyWork {

    public static void main(String[] args) {

        MyNetPack my = new MyNetPack();
        for (long i = 1; i < 100000000; i++) {
            my.reinit(i);
            my.process();
        }
    }
}

I'm creating single object by using

MyNetPack my=new MyNetPack();

Afterwards reusing the same object with the reinit method as follows,

for (long i = 1; i < 100000000; i++) {
    my.reinit(i);
    my.process();
}

Please explain the initial memory allocation & reuse of memory in stack and heap level.

From my understanding,

MyNetPack reference holder will be allocated in stack and Object will be allocated in heap (with reference holder for count) . Each time in the for loop, The actual value of count (say 1,2,3..) will be allocated newly in heap and the reference will be placed in MyNetPack->count reference holder.

Guide me to minimize new object & memory allocation..

Thanks Joseph

3
  • I don't think it would reserve new space for each number through the iteration of the loop, it would simply change the value that is already in the reserved heap memory. Commented May 8, 2014 at 14:15
  • It would be more or less true for reference types but since long is a primitive type, this isn't the case. Commented May 8, 2014 at 14:16
  • I want to reduce the GC as much as possible... Commented May 8, 2014 at 14:35

3 Answers 3

1

If you want to reduce the amount of garbage that this application creates, use long instead of Long in the MyNetPack class.

While the autoboxing long to Long may reuse existing Long objects, it won't do this for large integer values.

(Incidentally, in your example you never actually autobox any long value more than once. This means that the Long cache doesn't actually save any memory or reduce the number of allocations. If anything, it increases both your application's memory usage, and the number of allocations.)


On the other hand, you may have a sound reason to use Long instead of long. In that case, you will be pleased to know that the JVM's memory management is tuned so that the overheads of allocating and garbage collecting a short-lived object are small. The overheads are typically smaller than malloc / free in C or new / dispose in C++.

Sign up to request clarification or add additional context in comments.

Comments

0
my.reinit(i);

yes, every time you will get new object in heap. Autoboxing and Unboxing http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

Comments

0

Since long is a primitive type, the field count contains the number itself and not a reference to the number.

Therefore there won't be any extra heap allocation at each iteration.

Update: I've just seen the catch, the field is of type Long. In that case, the number will indeed be autoboxed into a newly created object, except if the number is <=128, in which case you'll always get the same reference from a pool.

As Stephen says, the solution is not to use Long but use the primitive long. My rule of thumb is never to use the wrapping classes of primitive types (Integer, Long, Float, Double etc.) unless I explicitly need a null-able field. As far as I can tell, that's the only valid reason to use them.

So for example if you have something like this:

public class Foo {
  private Long bar;

  public void setBar( long bar ) {
    this.bar = bar; // Autoboxing (and object allocation takes places here!!
  }

  public void doStuff() {
    if (bar == null) { //if the type of bar was long, its uninitialised value would be 0 but what if 0 is a valid value?
      throw new IllegalStateException( "bar not initialised" );
    //...do stuff here with bar, safe in the knowledge that it had been set to a meaningful value
  }
}

(Note that this is just an example, I wouldn't recommend it as a design pattern.)

5 Comments

Thanks bizclop, is there any way to avoid new obeject creation (for >128)?
I want to reduce the GC as much as possible... Any one can help?
@user2170066 Why then do you use Long?
If null is not legal in any operation then it should be prohibited ASAP, i.e., in the setter. The next step is to use primitive long instead and drop the check.
@maaartinus As you can see, it is prohibited in the setter. But it's still fairly poor design because doStuff() only works if you call setBar() before it. Which is why I added the disclaimer to the end: it's just a quick and short example of why you would use the wrapping classes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.