Andrew David
Andrew David

Reputation: 81

JVM YoungGen 0%, Perm Gen 99%, OldGen Full

I have a JEE application that has recently started to see spikes in CPU usage (e.g. 100% of 27 cores on a 40 core server) and increasingly longer periods of time where the application is unavailable. It's very similar behavior to the issue described in the following post, to include the fact that bouncing the application server makes the issue go away until it appears again after a few hours:

Old Gen heap is full and the Eden and Survivor are low and almost empty

I've taken some core dump outputs while the application is experiencing these "freezes" and I am seeing the following JVM GC output:

PSYoungGen total 11221504K, used 2435K
eden space 9238528K, 0% used
from space 19829796K, 0% used
to space 1970176K, 0% used
ParOldGen total 39613440K, used 39276477K
object space 39613440K, 99% used
PSPermGen total 254976K, used 115497K
object space 254976K, 45% used

Based on the referenced post and the above output, I think I understand that the "freezes" are being driven by the garbage collector running (in vain?) on the ParOldGen space. The parts I am missing:

  1. Why the PermGen space remains at 45% used. That is, will the ~39GB of stuff in ParOldGen ultimately transition into PSPermGen?

  2. What is the significance of the nearly empty PSYoungGen space? Does this mean that the application isn't creating any/many new object instances at steady state?

The post above also describes the option of "giving more headroom" to ParOldGen, but I'm not clear if that means increasing the total heap size via -Xmx or if there's an explicit JVM GC parameter. I see the NewRatio argument controls the size of the young generation relative to the old generation. Would the fact that the PSYoungGen is essentially empty mean that it's too large, and that I should use a smaller NewRatio value?

Thanks in advance for any assistance.

Upvotes: 4

Views: 5747

Answers (2)

Ravindra babu
Ravindra babu

Reputation: 38950

Why the PermGen space remains at 45% used. That is, will the ~39GB of stuff in ParOldGen ultimately transition into PSPermGen?

No. OldGen & PermGen spaces can't be shared. PSPermGen mostly contains classes loaded by class loader in PermGen space. ParOldGen contains heap memory for long lived objects.

In JDK 1.8, PermGen has replaced by Metaspace. Refer to this article for more details.

Refer to below SE questions for more details:

Java heap terminology: young, old and permanent generations?

What is the significance of the nearly empty PSYoungGen space? Does this mean that the application isn't creating any/many new object instances at steady state?

@Peter Lawrey has correctly answered it. After Full GC, YoungGen is nearly empty => you did not accumulate garbage from short lived objects in your application

The post above also describes the option of "giving more headroom" to ParOldGen, but I'm not clear if that means increasing the total heap size via -Xmx or if there's an explicit JVM GC parameter.

Your old gen is full implies that your application is retaining heap from long lived objects.

Now you have to check possible memory leaks (if any) in your application using profiling tools like visualvm or MAT

If you don't have memory leaks, you can increase your heap size with -Xmx.

Would the fact that the PSYoungGen is essentially empty mean that it's too large, and that I should use a smaller NewRatio value?

Since you are using larger heaps, I recommend you to use G1GC algorithm. If you use G1GC algorithm, don't customize default values since G1GC algorithm takes care of better heap management.

Have a look at oracle article on G1GC switches (Complete List of G1 GC Switches section), Use Cases article and related SE question:

Java 7 (JDK 7) garbage collection and documentation on G1

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533750

will the ~39GB of stuff in ParOldGen ultimately transition into PSPermGen?

The PermGen in Java 7 (replaced with metaspace in Java 8) is for holding code. The only things which pass from the heap to PermGen is byte code, so unless you are generating or loading classes, nothing passes from one to the other. They are different spaces.

What is the significance of the nearly empty PSYoungGen space?

The young gen is empty after a full GC. Full GCs are common once your old gen starts to fill up.

Does this mean that the application isn't creating any/many new object instances at steady state?

It is more likely to mean it has recently Full GC-ed.

describes the option of "giving more headroom" to ParOldGen, but I'm not clear if that means increasing the total heap size via -Xmx or if there's an explicit JVM GC parameter.

Increasing the maximum heap could give you more head room, but I would first check

  • you don't have a memory leak.
  • you can't move the bulk of your data off heap e.g. a database or native memory.

Would the fact that the PSYoungGen is essentially empty mean that it's too large, and that I should use a smaller NewRatio value?

That could help give you more space for the old gen, but it might just give you a bit more time before it runs out of memory.

Upvotes: 1

Related Questions