Java unrequested memory allocation
The following piece of code observed under JConsole shows a constant increase of the heap size. The heap reach a maximum of 25mb and then the GC runs and decease the he开发者_开发知识库ap size to almost 3MB. Is this the expected behavior ? I'm very surprised!
public class Dummy {
public static void main(String[] args) {
System.out.println("start");
while(true){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
I'm using Snow Leopard.
Communication with jconsole causes objects to be allocated. I believe what you are seeing here is is an artifact of your measurement method. There may also be slight allocation by HotSpot when compiling code. If you are worried, use a profiler to see what is being allocated (again, watch out for allocations by the profiler's interface).
Normal GC behaviour is to avoid running unnecessarily. You will see all over the web sawtooth graphs of memory usage. There is some compromise here between cache and swap friendliness and avoiding work. Also server HotSpot is more aggressive about using up memory than the client HotSpot.
Yes, this should be the expected behaviour. While you are not doing anything specific to allocate objects, the implementation of sleep might be, and even if that doesn't, there are other threads running in the JVM, that could well be.
Yes, it's normal. You're not explicitly creating any objects, but you're calling methods that probably create some temporary objects as part of their implementation. Those temporary objects pile up until it's time for a GC run to clean them out.
The class files looks like that, the code loops from 8 to 14, and java.lang.Thread.sleep() is native. Therefore there is no reason to create MB's of objects
public static void main(java.lang.String[] args);
0 getstatic java.lang.System.out : java.io.PrintStream [16]
3 ldc <String "start"> [22]
5 invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]
8 ldc2_w <Long 5000> [30]
11 invokestatic java.lang.Thread.sleep(long) : void [32]
14 goto 8
17 astore_1 [e]
18 aload_1 [e]
19 invokevirtual java.lang.InterruptedException.printStackTrace() : void [38]
22 goto 8
I'm afraid what you see is from JProfiler itself (I don't know how you attached it to your Dummy test app) or other things running in this vm. To find out what objects have been created you should do a heap dump if JProfiler doesn't show this information.
'
There are clearly two theories as to the cause, and it is not possible to distinguish them based on empirical reasoning. Can I suggest a simple experiment.
Change the program to sleep for 1 millisecond instead of 5000. (The actual number doesn't matter ... this is to make the hypothesized memory allocation happen as fast as possible. You could also try 0 milliseconds, but the behaviour of sleep may well be different ...)
Run the program using the current approach; e.g. with jconsole.
Run the program without jconsole, etc, but with the "-verbose:gc" option so that you can see when the GC runs.
I suspect that you will run out of patience waiting for the GC to run in the last case ... even calling sleep
as fast as possible.
精彩评论