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

Absurd-Mind
  • 7,884
  • 5
  • 35
  • 47
Joseph
  • 39
  • 5
  • 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. – Rogue May 08 '14 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. – biziclop May 08 '14 at 14:16
  • I want to reduce the GC as much as possible... – Joseph May 08 '14 at 14:35

3 Answers3

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++.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
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.)

Community
  • 1
  • 1
biziclop
  • 48,926
  • 12
  • 77
  • 104
  • Thanks bizclop, is there any way to avoid new obeject creation (for >128)? – Joseph May 08 '14 at 14:29
  • I want to reduce the GC as much as possible... Any one can help? – Joseph May 08 '14 at 14:31
  • @user2170066 Why then do you use `Long`? – Ingo May 08 '14 at 14:32
  • 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 May 08 '14 at 15:20
  • @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. – biziclop May 08 '14 at 15:24
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

Mike Demidov
  • 1,117
  • 11
  • 20