JDK-6736341 : PermGen size is insufficient for jconsole
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: hs14
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2008-08-12
  • Updated: 2012-10-01
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u14Fixed 7Fixed hs14Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
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.

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

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.

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.

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.

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);