OrangeMan
OrangeMan

Reputation: 692

Do you save the garbage collector work by declaring in-method variables as attributes?

Compare

public class Core {

    public int addToA(int a) {
        int b = a + 2;
        return b;
    }
}

To

public class Core {

    int b;

    public int addToA(int a) {
        b = a + 2;
        return b;
    }
}

Assuming that the addToA method is called a lot do you save the garbage collector work (and speed up your program) by using the second one?

Upvotes: 3

Views: 115

Answers (4)

Nigel Tufnel
Nigel Tufnel

Reputation: 11534

javap -v Core to the rescue!

Field version disassembles to:

 0: aload_0
 1: iload_1
 2: iconst_2
 3: iadd
 4: putfield      #2                  // Field b:I
 7: aload_0
 8: getfield      #2                  // Field b:I
11: ireturn

Local variable version disassembles to:

 0: iload_1
 1: iconst_2
 2: iadd
 3: istore_2
 4: iload_2
 5: ireturn

Local variable version in plain english:

  1. Load an int value from local variable 1
  2. Load the int value 2 onto the stack
  3. Add ints loaded at steps 1 and 2
  4. Store int value into variable 2
  5. Load an int value from local variable 2
  6. Return an integer from a method

There is no heap memory allocation performed during the addToA call. Everything is done on the stack. Garbage collector rests.

Upvotes: 3

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 280122

Local variables are allocated on the stack.

In this case

public int addToA(int a) {
    int b = a + 2;
    return b;
}

when the method returns, and the stack frame containing b is popped, the memory it was taking will be recovered automatically. The Garbage Collector is not involved.

In this case

public class Core {

    int b;

    public int addToA(int a) {
        b = a + 2;
        return b;
    }
}

b will be allocated in the heap space reserved for the Core object. It will only be garbage collected when Core is collected.

Assuming that the addToA method is called a lot do you save the garbage collector work (and speed up your program) by using the second one?

As far as I know, you won't gain anything.

Go read T.J. Crowder's Community Wiki post for an example on when to and when not to do what you are proposing.

Upvotes: 7

T.J. Crowder
T.J. Crowder

Reputation: 1075119

In your example, b will be on the stack, not in the heap, and so it will be reclaimed when the stack frame is popped. No savings for the GC at all. This is true for all local variables in methods.

The heap gets involved if you allocate an object, rather than just having a variable. Because the value you're assigning b is a primitive, that doesn't come into play here.

But for instance, suppose it were:

StringBuilder sb = new StringBuilder();

Now you have a variable on the stack, which holds a reference to an object in the heap. In theory, you could save the GC work (at the cost of higher memory use) by having one of those that you reused. But you'd have to reuse the StringBuilder, not the variable. In practice, any savings are likely to be washed out by effort needed to reset the object to a blank state, complexity, and (again) higher ongoing memory use.

(And note that some JVMs may do smart things you'd be interfering with, like putting objects on the stack and moving them to the heap if a reference to the object survives the termination of the method call. I know V8 does that in the JavaScript world, and V8 gets a lot of inspiration from Sun's JVM, so...)

Upvotes: 3

Martijn Courteaux
Martijn Courteaux

Reputation: 68887

Local variables are always declared on the stack (so do not mix up with class members, these are on the heap). The garbage collector is a tool that takes care of the heap memory. So both are totally different. Variables on the stack will just pop of as the scope was left (eg: the method returned).

Upvotes: 1

Related Questions