An application server is running on JVM 1.3.1.13, but data segment
sometimes grows above 400MB and it looks like a memory leak.
$ /opt/java1.3/bin/java -classpath myc.jar:. Main &
// run glance and check memory region
Type RefCt RSS VSS Locked File Name
--------------------------------------------------------------
TEXT /Priv 1 24kb 28kb 0kb /opt/.../java
DATA /Priv 1 649.0mb 652.0mb 0kb /opt/.../java
MEMMAP/Priv 1 36kb 516kb 0kb <mmap>
If the process hits maxdsiz limit, it would crash with following
message:
Stack_Trace: error while unwinding stack
( 0) 0xc448f048 vm_exit_out_of_memory__FiPCcb + 0x268 ...
( 1) 0xc4406cf4 grow__5ArenaFUl + 0x94 ...
( 2) 0xc45b4c70 resource_allocate_bytes__FUl + 0x70 ...
( 3) 0xc444bd98 init_basic_blocks__14GenerateOopMapFv + 0x320 ...
( 4) 0xc444ba00 do_interpretation__14GenerateOopMapFv + 0x30 ...
( 5) 0xc4451850 compute_map__14GenerateOopMapFv + 0x280 ...
( 6) 0xc4453478
do_potential_rewrite__22ResolveOopMapConflictsFP6Thread + 0x20 ...
( 7) 0xc45b5088
rewrite_method__8RewriterSF12methodHandleP13GrowableArrayXTi_P6Thread +
0x148 ...
( 8) 0xc45b5488 rewrite__8RewriterSF19instanceKlassHandleP6Thread +
0xa0 ...
( 9) 0xc4464454
link_class_impl__13instanceKlassSF19instanceKlassHandleP6Thread +
0x68c
...
(10) 0xc446470c
initialize_impl__13instanceKlassSF19instanceKlassHandleP6Thread +
0x1dc
...
(11) 0xc44635f8 initialize__13instanceKlassFP6Thread + 0xb8 ...
(12) 0xc44fa128 JVM_FindClassFromClassLoader + 0x2f8 ...
It looks like JVM allocates large heap when loading a class which has
many 'jsr' bytecodes and exception table slots for 'any'. 1.3 java
compiler generates such class if java source has many try/finally.
I see this type of method in the classes generated from large JSP.
Class loader needs to perform rewrite operation for the methods which
have 'jsr' bytecode and the rewrite operation allocates memory for
blocks in the method. If the method has many blocks (many 'jsr' or
many exception table entries), larger memory is allocated.
The original application program starts 26 threads and each looks up and instantiates five classes. Once all the threads exit, the main thread sleeps for 1000 seconds. The class loaded from the thread has 500 try/finally clauses in a method.
If I compile the classes which has many try/finally clauses using
1.4 javac, then the program can run with about 30MB C-heap. It looks
like 1.4 java compiler avoids emitting 'jsr' if possible and use 'goto' instead.
If I load only one such class compiled by 1.3 javac, it makes data
segment size about 24MB. If I use a class compiled by 1.4 javac,
data segment size is about 4MB. (I have enclosed the sample program which loads one class)
Here is the prstat output on solaris for the application compiled with 1.3.1
javac
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
25619 sandyam 390M 372M sleep 52 0 0:00.12 19% java/33
With 1.4 javac, here is the output
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
25595 sandyam 49M 31M run 59 0 0:00.02 0.0% java/8
The memory growth is due to state vector being maintained for each Basic Block. I can reproduce the same situation in sun
Hotspot JVM as well, (The memory allocated is 389 MB compared to 500+ MB in our case). In my opinion, this allocation is because, since the JVM needs to know the BB state for doing the abstract interpretation as part of oop map computation.
The memory use looks too much. The operation should be checked and changed to avoid the excessive memory use.
We have attached a small sample testcase which loads only one class which contains 500 try/finally clauses. Please see MainOne.java and class000.java. We can send the complete jar files of the testcase thru mail) Here itself the difference shows up, It takes around 24MB for this one class when using classfiles compiled with 1.3.1 javac, whereas it takes only 4 MB around when using class files compiled with 1.4 javac
test case is attached.
###@###.### 2005-1-18 19:27:37 GMT
sometimes grows above 400MB and it looks like a memory leak.
$ /opt/java1.3/bin/java -classpath myc.jar:. Main &
// run glance and check memory region
Type RefCt RSS VSS Locked File Name
--------------------------------------------------------------
TEXT /Priv 1 24kb 28kb 0kb /opt/.../java
DATA /Priv 1 649.0mb 652.0mb 0kb /opt/.../java
MEMMAP/Priv 1 36kb 516kb 0kb <mmap>
If the process hits maxdsiz limit, it would crash with following
message:
Stack_Trace: error while unwinding stack
( 0) 0xc448f048 vm_exit_out_of_memory__FiPCcb + 0x268 ...
( 1) 0xc4406cf4 grow__5ArenaFUl + 0x94 ...
( 2) 0xc45b4c70 resource_allocate_bytes__FUl + 0x70 ...
( 3) 0xc444bd98 init_basic_blocks__14GenerateOopMapFv + 0x320 ...
( 4) 0xc444ba00 do_interpretation__14GenerateOopMapFv + 0x30 ...
( 5) 0xc4451850 compute_map__14GenerateOopMapFv + 0x280 ...
( 6) 0xc4453478
do_potential_rewrite__22ResolveOopMapConflictsFP6Thread + 0x20 ...
( 7) 0xc45b5088
rewrite_method__8RewriterSF12methodHandleP13GrowableArrayXTi_P6Thread +
0x148 ...
( 8) 0xc45b5488 rewrite__8RewriterSF19instanceKlassHandleP6Thread +
0xa0 ...
( 9) 0xc4464454
link_class_impl__13instanceKlassSF19instanceKlassHandleP6Thread +
0x68c
...
(10) 0xc446470c
initialize_impl__13instanceKlassSF19instanceKlassHandleP6Thread +
0x1dc
...
(11) 0xc44635f8 initialize__13instanceKlassFP6Thread + 0xb8 ...
(12) 0xc44fa128 JVM_FindClassFromClassLoader + 0x2f8 ...
It looks like JVM allocates large heap when loading a class which has
many 'jsr' bytecodes and exception table slots for 'any'. 1.3 java
compiler generates such class if java source has many try/finally.
I see this type of method in the classes generated from large JSP.
Class loader needs to perform rewrite operation for the methods which
have 'jsr' bytecode and the rewrite operation allocates memory for
blocks in the method. If the method has many blocks (many 'jsr' or
many exception table entries), larger memory is allocated.
The original application program starts 26 threads and each looks up and instantiates five classes. Once all the threads exit, the main thread sleeps for 1000 seconds. The class loaded from the thread has 500 try/finally clauses in a method.
If I compile the classes which has many try/finally clauses using
1.4 javac, then the program can run with about 30MB C-heap. It looks
like 1.4 java compiler avoids emitting 'jsr' if possible and use 'goto' instead.
If I load only one such class compiled by 1.3 javac, it makes data
segment size about 24MB. If I use a class compiled by 1.4 javac,
data segment size is about 4MB. (I have enclosed the sample program which loads one class)
Here is the prstat output on solaris for the application compiled with 1.3.1
javac
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
25619 sandyam 390M 372M sleep 52 0 0:00.12 19% java/33
With 1.4 javac, here is the output
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
25595 sandyam 49M 31M run 59 0 0:00.02 0.0% java/8
The memory growth is due to state vector being maintained for each Basic Block. I can reproduce the same situation in sun
Hotspot JVM as well, (The memory allocated is 389 MB compared to 500+ MB in our case). In my opinion, this allocation is because, since the JVM needs to know the BB state for doing the abstract interpretation as part of oop map computation.
The memory use looks too much. The operation should be checked and changed to avoid the excessive memory use.
We have attached a small sample testcase which loads only one class which contains 500 try/finally clauses. Please see MainOne.java and class000.java. We can send the complete jar files of the testcase thru mail) Here itself the difference shows up, It takes around 24MB for this one class when using classfiles compiled with 1.3.1 javac, whereas it takes only 4 MB around when using class files compiled with 1.4 javac
test case is attached.
###@###.### 2005-1-18 19:27:37 GMT