Bhaskar Na
Bhaskar Na

Reputation: 1

jmap -permstat takes long time and hangs

We started seeing 'java.lang.OutOfMemoryError: PermGen space'. In order to findout what is held in perm space, tried running

'/usr/j2sdk1.6.0_13/bin/jmap -permstat 20476 -J-mx1280m > /tmp/permstats20476.txt &'

This command is taking long time ..... in between it gave below exception:

finding class loader instances ..252829 intern Strings occupying 30781792 bytes. Finding object size using Printezis bits and skipping over... Finding object size using Printezis bits and skipping over... Finding object size using Printezis bits and skipping over... Finding object size using Printezis bits and skipping over...

done. computing per loader stat ..done. please wait.. computing liveness...................Exception in thread "Thread-1" java.lang.OutOfMemoryError: GC overhead limit exceeded at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.readBytesFromProcess0(Native Method) at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.access$1000(LinuxDebuggerLocal.java:51) at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$1ReadBytesFromProcessTask.doit(LinuxDebuggerLocal.java:558) at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.run(LinuxDebuggerLocal.java:127)

but it is not completing ...

[svcmig2@app430 ~]$ uname -a Linux app430... 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

is there any other alternates to jmap ? so that i get the perm stats fast

Upvotes: 0

Views: 2477

Answers (2)

javadu
javadu

Reputation: 21

  1. You can set the JVM args: -XX:+HeapDumpOnOutOfMemoryError to get .hprof file when the oom arise, then use mat to analysis the duplicate loaded classes.

  2. I have write a tool class with SA for your question. My JDK version is 1.8.0_151.

Here is source code:

import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.tools.Tool;

/**
 * @author duqi
 * @createTime 2018/9/1 下午11:55
 **/
public class PermTool extends Tool {
    @Override
    public void run() {
        // Show PermGen object histogram
        ObjectHistogram histo = new ObjectHistogram();
        VM.getVM().getObjectHeap().iterate(histo);
        histo.print();

        // List all classes in PermGen with their ClassLoaders
        VM.getVM().getObjectHeap().iterate(new DefaultHeapVisitor() {

            @Override
            public boolean doObj(Oop obj) {
                if (obj.getKlass() instanceof InstanceKlass) {
                    obj.printValue();
                    Oop loader = ((InstanceKlass) obj.getKlass()).getClassLoader();
                    if (loader == null) {
                        System.out.println(" -- loaded by Bootstrap ClassLoader");
                    } else {
                        System.out.print(" -- loaded by ");
                        loader.printValue();
                        System.out.println();
                    }
                }
                return false;
            }
        });
    }

    public static void main(String[] args) {
        new PermTool().execute(args);
    }
}

Upvotes: 2

apangin
apangin

Reputation: 98560

is there any other alternates to jmap ? so that i get the perm stats fast

You can make one yourself! This is really easy with the aid of Serviceability Agent.

Here is an example for your case:

import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.tools.Tool;

public class PermTool extends Tool {

    @Override
    public void run() {
        // Show PermGen object histogram
        ObjectHistogram histo = new ObjectHistogram();
        VM.getVM().getObjectHeap().iteratePerm(histo);
        histo.print();

        // List all classes in PermGen with their ClassLoaders
        VM.getVM().getObjectHeap().iteratePerm(new DefaultHeapVisitor() {
            @Override
            public boolean doObj(Oop obj) {
                if (obj instanceof InstanceKlass) {
                    obj.printValue();
                    Oop loader = ((InstanceKlass) obj).getClassLoader();
                    if (loader == null) {
                        System.out.println(" -- loaded by Bootstrap ClassLoader");
                    } else {
                        System.out.print(" -- loaded by ");
                        loader.printValue();
                        System.out.println();
                    }
                }
                return false;
            }
        });
    }

    public static void main(String[] args) {
        new PermTool().start(args);
    }
}

Just compile and run it using the same JDK as your target process.
Make sure jdk/lib/sa-jdi.jar is on the CLASSPATH.

Upvotes: 2

Related Questions