United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6736341 PermGen size is insufficient for jconsole
6736341 : PermGen size is insufficient for jconsole

Details
Type:
Bug
Submit Date:
2008-08-12
Status:
Closed
Updated Date:
2012-10-01
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
generic,windows_xp
Sub-Component:
gc
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
hs14
Fixed Versions:
hs14

Related Reports
Backport:
Backport:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

Description
If we try to monitor an application using jconsole from JDK7b33/HS14-b03 on windows-i586, it reports many OutOfMemoryError: PermGen space errors and does not work properly.

The problem does not occur on windows-amd64. Also, it goes away if we increase PermGen size using -J-XX:PermGen=128m.

To reproduce:

<log into intelsdv14.sfbay, cheesepuff.sfbay or vm-amd64-00.sfbay>
$ cd s:/comp/vm/jdk/7/nightly/product/main_baseline/windows-i586
$ bin/jconsole localhost:0

It seems like a HS14 problem, not a JConsole one: if I start Jconsole using jconsole.jar from this JDK7 and java from JDK 6u6p/HS13-b04, everything works fine.

                                    

Comments
SUGGESTED FIX

It turns out that the grow_by() and grow_to_reserved() methods in CompactingPermGenGen were not actually called before the fix for 6730514. And taking into account _share_space_size in the virtual space is incorrect, as the virtual space does not actually include the shared space. So, the correct fix is to remove those two methods from CompactingPermGenGen so that the methods in their superclass are called instead.
                                     
2008-08-20
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/1e5d20c34408
                                     
2008-08-20
EVALUATION

This looks to have been introduced by the fix for 6730514. I also discovered it when I was evaluating a similar failure when merging the changes in G1. The evaluation is the following.

The path, during perm gen expansion, before the merge was the following:

PermGen::mem_allocate_in_gen()
OneContigSpaceCardGeneration::expand_and_allocate()
OneContigSpaceCardGeneration::expand()
OneContigSpaceCardGeneration::grow_by()

Post-merge the path is the following:

PermGen::mem_allocate_in_gen()
OneContigSpaceCardGeneration::expand_and_allocate()
OneContigSpaceCardGeneration::expand()
CardGeneration::expand()
CompactingPermGenGen::grow_by()
OneContigSpaceCardGeneration::grow_by()

It's CompactingPermGenGen::grow_by() that's buggy (see below) and it was not showing up before because it was not being called (at least in the G1 workspace). The changes that I picked up through the merge were

- CardGeneration::expand() was introduced
- virtual CardGeneration::grow_by() == 0 was introduced
- OneContigSpaceCardGeneration::grow_by() was made into a virtual method

So, before, OneContigSpaceCardGeneration::expand() would call grow_by() and go to OneContigSpaceCardGeneration::grow_by().

Now, OneContigSpaceCardGeneration::expand() delegates to CardGeneration::expand(), which calls grow_by() and goes to CompactingPermGenGen::grow_by(), because of the introduction of the virtual grow_by() in CardGeneration (even though CompactingPermGenGen::grow_by() is not declared virtual, now there is a virtual grow_by() declared up in the hierarchy). 
The bug in OneContigSpaceCardGeneration::expand() is the following:

 // Don't allow _virtual_size to expand into shared spaces.
 size_t max_bytes = _virtual_space.uncommitted_size() - _shared_space_size;
 if (bytes > _shared_space_size) {
   bytes = _shared_space_size;
 }
 return OneContigSpaceCardGeneration::grow_by(bytes);

When _shared_space_size == 0, bytes will always become 0 and never allow the perm gen to expand. The right version seems to be:

 // Don't allow _virtual_size to expand into shared spaces.
 size_t max_bytes = _virtual_space.uncommitted_size() - _shared_space_size;
 if (bytes > max_bytes) {
   bytes = max_bytes;
 }
 return OneContigSpaceCardGeneration::grow_by(bytes);
                                     
2008-08-15
EVALUATION

I should add that, as far as I can see, this bug is currently preventing the perm gen from growing from its initial size.
                                     
2008-08-15
EVALUATION

While looking at the code, discovered another problem in the nearby method CompactingPermGenGen::grow_to_reserved()--it returns false when the gen is already expanded to the maximum size.  The other implementations of grow_to_reserved(), in ConcurrentMarkSweepGeneration and OneContigSpaceCardGeneration, return true if the gen is already expanded to the max size.  This may be a benign problem, but hard to be sure.
                                     
2008-08-15



Hardware and Software, Engineered to Work Together