Do most JVMs allocate memory for unused methods?
Asked Answered
V

5

11

Say we have the following classes:

class DoubleOhSeven {
  public static void doSomethingClassy();
  public static void neverDoThisClassy();
}

class Dude {
  public void doSomething();
  public void neverDoThis();
}

public class Party {
  public static void main(String[] args){
    DoubleOhSeven.doSomething();
    Dude guy = new Dude;
    guy.doSomething();
  }
}

Of course, all the methods will be compiled into their respective .class: do the unused static/instance methods occupy memory at run time? What about unused inherited or imported methods?

Viehmann answered 24/11, 2012 at 8:46 Comment(0)
L
13

The unused methods are still there occupying memory as part of the class / object, even if they're not directly called.

If they were optimised away, then that would make reflective calls on these methods impossible.

One could argue that an optimisation could be generated that only stored the method stub in memory, and garbage collected the method contents (which would then be re-fetched from the class file if a call was made.) However, I'm not aware of a VM which does this, and it would be hard to justify due to the likely minimal gains in memory and tradeoff in speed whenever such a method was called.

Unused inherited methods would be exactly the same.

Lunatic answered 24/11, 2012 at 8:50 Comment(2)
You mean reflective calls from some other class?Viehmann
@faraz Or that class itself - since reflective method calls are, by definition, decided at runtime and not compile time, the compiler has no way of knowing what reflective methods will be called or when.Lunatic
G
4

The memory used by an instance of a class Abc does not depend on how many methods there are in Abc.

The generated bytecode obviously does increase in size when you add methods, whether they do something or not, but that would only affect the size of the class object Abc.class, which is loaded only once, regardless of how many instances are created.

Glim answered 24/11, 2012 at 9:25 Comment(0)
U
2

Since classes are safed in ther PermGen for Sun Hotspot JVMs (that will change for Java 8), you can do something like this, first run:


MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
long before = memoryMXBean.getNonHeapMemoryUsage().getUsed();
new Dude(); // class must not be loaded before
System.out.println("Usage of dude is " + (memoryMXBean.getNonHeapMemoryUsage().getUsed() - before) + " bytes");

And you will see something like this: Usage of dude is 6432 bytes

And then create a Dude class without the unused method and run the test:


MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
long before = memoryMXBean.getNonHeapMemoryUsage().getUsed();
new DudeWithoutNeverDoThis(); // must not be loaded before
System.out.println("Usage of dude without 'nerverDoThis' is " + (memoryMXBean.getNonHeapMemoryUsage().getUsed() - before) + " bytes");

and you see the difference (Usage of dude without 'nerverDoThis' is 6176 bytes)

Uela answered 24/11, 2012 at 9:25 Comment(1)
It would be interesting to get the numbers again after a method on the class had actually been called, and then been called 1000 times. Calling the method lots of times provokes HotSpot into compiling it to native code, which will take up memory.Streamlet
M
1

The unused methods inrease the class size, but classes are stored in a so called PermGen memory. The heap memory, where regular java objects are stored, is not affected by class size

Microreader answered 24/11, 2012 at 9:21 Comment(0)
M
0

The method can be compiled and loaded to PerGen.

But JVM maybe optimize method using method inlining.

Eg:

public class Test {

    public void foo(){
        System.out.println("foo");
        bar();
    }

    public void bar(){
        System.out.println("bar");
    }
}

The method will be compiled like this by JIT compiler:

public void foo(){
    System.out.println("foo");
    System.out.println("bar");
}

So, the empty method will never be invoked.

Milzie answered 26/11, 2012 at 3:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.