BMF
BMF

Reputation: 307

memory allocation for variables in java

I have a question about how java deals with unused variables.

Let's say that i have the following code:

int notUsedVariable = aMethodThatExecutesSomethingImportantAndReturnsInt(someParameter);

Then I never use notUsedVariable in the code. Will that variable actually be stored, or java is smart enough to ignore the variable when compiling?

Thanks!

Upvotes: 2

Views: 2576

Answers (6)

Mike Strobel
Mike Strobel

Reputation: 25623

My observation has been that javac may omit the store operations of unused variables if:

  1. The variables are marked as final and are initialized in the declaration;
  2. You do not compile with local variable debug info (-g:vars)

If you compile with -g:vars, javac will keep the variables loads and stores in tact for debugging purposes. It does not appear to consider non-final variables as eligible for removal.

Test for yourself. My results with JDK 7 are below. The results were identical with a JDK 8 EAP.

Input:

class MyTest {
    public static void main(String... args) {
        int a = 1;
    }
}

Output:

public static void main(java.lang.String... p0);
  Flags: PUBLIC, STATIC, VARARGS
  Code:
    stack=1, locals=2, arguments=1
         0: iconst_1
         1: istore_1
         2: return

Input:

class MyTest {
    public static void main(String... args) {
        final int a = 1;
    }
}

Output:

public static void main(java.lang.String... p0);
  Flags: PUBLIC, STATIC, VARARGS
  Code:
    stack=1, locals=2, arguments=1
         0: return

As others have said, in either case I would expect the JIT optimizer to omit any unnecessary store operations.

Upvotes: 5

iowatiger08
iowatiger08

Reputation: 1962

It will be stored based upon the scope of the variable that when the scope ends, garbage collection will clean up the memory used by the variable.

I edited once of my Test classes for a class variable and local variable and then used Eclipse to inspect the class file. (Eclipse complains that the variable is never used.)

// Compiled from UserLoadTest.java (version 1.6 : 50.0, super bit)
public class org.dev.user.UserLoadTest extends org.test.BaseTestCase {

  // Field descriptor #6 I
  public int myVariable;

...we can see that the class file sees this

@org.junit.Test
  public void testBasicUserLoad() throws java.io.IOException, org.custommonkey.xmlunit.exceptions.XpathException;
      0  aload_0 [this]
      1  ldc <String "user_01.xml"> [24]
...
org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo(java.lang.String, java.lang.String, org.w3c.dom.Document) : void [85]
    223  aload_2 [reloaded]
    224  invokevirtual org.testHarness.Result.getDocument() : org.dom4j.dom.DOMDocument [81]
    227  astore_3 [d]
    228  return

line 224 is a simple declaration of a variable using

    Document d = reloaded.getDocument();

This does nothing with d but the class file recognizes that the variable was created.

Upvotes: 0

Grzegorz Żur
Grzegorz Żur

Reputation: 49181

Let's compile an example

public class Test {
   public static void main(String... args) {
       int a = 1;
   }
}

We get

public class Test {
  public Test();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String...);
    Code:
       0: iconst_1       // push integer 1 on stack      
       1: istore_1       // pop integer from stack, store it in local variable 1
       2: return        
}

We can see that local variable was not removed. It was stored.

Please remember that at the time of execution optimizations may happen.

Upvotes: 2

Matt Ball
Matt Ball

Reputation: 359816

If you're concerned just about the static compilation step, and not the JIT, this is simple to check by comparing the bytecode generated from two slightly different classes, using javap:

class WithLocalVar {

    private static int methodWithSideEffect() {
        System.out.println();
        return 42;
    }

    public static void main(String[] args) {
        int result = methodWithSideEffect();
    }
}

class WithoutLocalVar {

    private static int methodWithSideEffect() {
        System.out.println();
        return 42;
    }

    public static void main(String[] args) {
        methodWithSideEffect();
    }
}

✗  javac With*
✗  javap -c WithLocalVar
Compiled from "WithLocalVar.java"
class WithLocalVar extends java.lang.Object{
WithLocalVar();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   invokestatic    #4; //Method methodWithSideEffect:()I
   3:   istore_1
   4:   return

}

✗  javap -c WithoutLocalVar
Compiled from "WithoutLocalVar.java"
class WithoutLocalVar extends java.lang.Object{
WithoutLocalVar();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   invokestatic    #4; //Method methodWithSideEffect:()I
   3:   pop
   4:   return

}

Therefore, no, the compiler won't optimize away the istore_1. The JIT is another story...

Upvotes: 2

assylias
assylias

Reputation: 328608

It depends.

If notUsedVariable is a local variable, the assignment will probably be ignored by the JIT compiler (but we are talking about one register read/write, i.e. sub-nanosecond stuff on modern desktop processors). As demonstrated by MattBall the bytecode will keep the assignment.

If notUsedVariable is a member of the class, the result will need to be stored as the field might be accessed later on and it would probably be impossible for the compiler to prove otherwise (a new class could be loaded that does not exist yet for example).

Upvotes: 3

Frank Sposaro
Frank Sposaro

Reputation: 8531

javac does not perform many optimizations. The JIT, on the other hand, does

Check out http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/

Here is a qoute.

More importantly, the javac compiler does not perform simple optimizations like loop unrolling, algebraic simplification, strength reduction, and others. To get these benefits and other simple optimizations, the programmer must perform them on the Java source code and not rely on the javac compiler to perform them.

There is also another thread going into more detail about this. Optimization by Java Compiler

Upvotes: 2

Related Questions