17

I've run the jmap -heap command on our running Java application and here's what I got:

C:\Program Files\Java\jdk1.7.0_05\bin>jmap -heap 2384 Attaching to process ID 2384, please wait... Debugger attached successfully. Server compiler detected.
JVM version is 23.1-b03

using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC

Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 1073741824 (1024.0MB)
NewSize = 1310720 (1.25MB)
MaxNewSize = 17592186044415 MB
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 134217728 (128.0MB)
MaxPermSize = 201326592 (192.0MB)
G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 228261888 (217.6875MB)
used = 203794000 (194.3531036376953MB)
free = 24467888 (23.334396362304688MB)
89.28078260703775% used
Eden Space:
capacity = 202964992 (193.5625MB)
used = 198399360 (189.2083740234375MB)
free = 4565632 (4.3541259765625MB)
97.75053226913141% used
From Space:
capacity = 25296896 (24.125MB)
used = 5394640 (5.1447296142578125MB)
free = 19902256 (18.980270385742188MB)
21.325304100550518% used
To Space:
capacity = 25296896 (24.125MB)
used = 0 (0.0MB)
free = 25296896 (24.125MB)
0.0% used
concurrent mark-sweep generation:
capacity = 506445824 (482.984375MB)
used = 159479408 (152.09141540527344MB)
free = 346966416 (330.89295959472656MB)
31.489924576809226% used
Perm Generation:
capacity = 134217728 (128.0MB)
used = 72157448 (68.81470489501953MB)
free = 62060280 (59.18529510498047MB)
53.76148819923401% used

96874 interned Strings occupying 89695496 bytes.

So it seems like there are approximately 89mb of interned strings in 68mb of Permgen. Are there interned strings that are not stored in the Permgen?

Vic
  • 21,473
  • 11
  • 76
  • 97
  • 1
    Why would you possibly care? I suspect you're trying to micromanage. – Hot Licks Apr 30 '13 at 11:02
  • @HotLicks - Because we're having a permgen OOM exceptions and I was trying to rule out string interning. Plus the curiosity of course :) – Vic Apr 30 '13 at 11:05

1 Answers1

24

From Java 7 release notes:

In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.

dcernahoschi
  • 14,968
  • 5
  • 37
  • 59
  • 1
    Note that this was a change in java 7. See also my answer [here](http://stackoverflow.com/a/14985144/758831) which has some useful links and pointers to how things are changing again in java 8. – wmorrison365 Apr 30 '13 at 10:57
  • Thanks! So the only thing left in permgen in Java 7 are classloaders? – Vic Apr 30 '13 at 11:11
  • The classloaders together with their loaded classes. I'm not aware of other changes regarding PermGen space from Java 6 to Java 7. – dcernahoschi Apr 30 '13 at 11:34
  • Yes, I believe so... well classloading remnants such as class structures, methods, class meta-information, etc. I've not profiled a java 7 JVM yet. Also, OOM's won't be resolved by this... they'll just occur in heapspace (for instance if the issue were interned strings). You either have more classes being loaded than your permgen space can hold or a classloader leak. Try the -XX:+TraceClassloading and -XX:+TraceClassUnloadin JAVA_OPTIONS to trace classloader behaviour. Also, make sure your -XX:MaxPermSize is sensible. – wmorrison365 Apr 30 '13 at 11:39
  • Also, also, have you tried just watching the permgen space using VisualGC? If you can provide use-cases, you could see where permgen is dramatically consumed. I've not tried VisualGC with java 7 but I wouldn't expect issues though I believe it's now been absorbed into [VisualVM](https://visualvm.java.net/). There is a useful guide to VisualGC [here](http://www.scalingbits.com/javaprimer#comment-48). – wmorrison365 Apr 30 '13 at 11:43
  • @wmorrison365 - thanks for the tips! As far as I saw VisualGC only shows the size of the Permgen, I didn't find a way to see its' contents. Am I right? – Vic Apr 30 '13 at 12:25
  • @Vic, ah yes that's right. I meant that you could see if a particular usecase caused a large increase. YourKit is a wonderful profiler with fantastic memory diagnostic capabilities. Perhaps [this link of theirs](http://www.yourkit.com/docs/kb/class_loaders.jsp) will be of help in your specific case. BTW, you can download a free 15day trial. Even then, it's good value to buy outright. – wmorrison365 Apr 30 '13 at 14:34