Skip to content

Instantly share code, notes, and snippets.

@rednaxelafx
Created January 11, 2012 07:18
Show Gist options
  • Save rednaxelafx/1593521 to your computer and use it in GitHub Desktop.
Save rednaxelafx/1593521 to your computer and use it in GitHub Desktop.

Revisions

  1. rednaxelafx revised this gist Nov 4, 2012. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions DirectMemorySize.java
    Original file line number Diff line number Diff line change
    @@ -75,13 +75,13 @@ address, toM(capacity), capacity,
    public static long getStaticLongFieldValue(String className, String fieldName) {
    InstanceKlass klass = SystemDictionaryHelper.findInstanceKlass(className);
    LongField field = (LongField) klass.findField(fieldName, "J");
    return field.getValue(klass);
    return field.getValue(klass); // on JDK7 use: field.getValue(klass.getJavaMirror());
    }

    public static int getStaticIntFieldValue(String className, String fieldName) {
    InstanceKlass klass = SystemDictionaryHelper.findInstanceKlass(className);
    IntField field = (IntField) klass.findField(fieldName, "I");
    return field.getValue(klass);
    return field.getValue(klass); // on JDK7 use: field.getValue(klass.getJavaMirror());
    }

    public static double toM(long value) {
  2. rednaxelafx revised this gist Apr 18, 2012. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions command_prompt3
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    [sajia@xxx164 gist]$ sudo -u admin java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize -e `pgrep -u admin java` | grep -v 'Finding object'
    Attaching to process ID 2499, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 20.0-b12-internal
    NIO direct memory: (in bytes)
    reserved size = 907.541405 MB (951626136 bytes)
    max size = 3925.375000 MB (4116054016 bytes)
    NIO direct memory malloc'd size: 910.697655 MB (954935704 bytes)
  3. rednaxelafx revised this gist Apr 18, 2012. 2 changed files with 4 additions and 4 deletions.
    4 changes: 2 additions & 2 deletions DirectMemorySize.java
    Original file line number Diff line number Diff line change
    @@ -49,7 +49,7 @@ public boolean doObj(Oop oop) {
    countHolder[0]++;

    if (verbose) {
    System.out.printf(" 0x%016x: reservedSize = %f MB (%d bytes),"
    System.out.printf(" 0x%016x: capacity = %f MB (%d bytes),"
    + " mallocSize = %f MB (%d bytes)\n",
    address, toM(capacity), capacity,
    toM(mallocSize), mallocSize);
    @@ -122,4 +122,4 @@ public static void main(String[] args) {
    tool.start(args);
    tool.stop();
    }
    }
    }
    4 changes: 2 additions & 2 deletions command_prompt2
    Original file line number Diff line number Diff line change
    @@ -65,8 +65,8 @@ NIO direct memory: (in bytes)
    reserved size = 0.000003 MB (3 bytes)
    max size = 7152.000000 MB (7499415552 bytes)
    Currently allocated direct buffers:
    0x00002aaab021df10: reservedSize = 0.000001 MB (1 bytes), mallocSize = 0.003907 MB (4097 bytes)
    0x00002aaab0843310: reservedSize = 0.000002 MB (2 bytes), mallocSize = 0.003908 MB (4098 bytes)
    0x00002aaab021df10: capacity = 0.000001 MB (1 bytes), mallocSize = 0.003907 MB (4097 bytes)
    0x00002aaab0843310: capacity = 0.000002 MB (2 bytes), mallocSize = 0.003908 MB (4098 bytes)
    Finding object size using Printezis bits and skipping over...
    Finding object size using Printezis bits and skipping over...
    NIO direct memory malloc'd size: 0.007815 MB (8195 bytes)
  4. rednaxelafx revised this gist Apr 18, 2012. 1 changed file with 12 additions and 0 deletions.
    12 changes: 12 additions & 0 deletions command_prompt2
    Original file line number Diff line number Diff line change
    @@ -29,6 +29,18 @@ NIO direct memory: (in bytes)
    Finding object size using Printezis bits and skipping over...
    Finding object size using Printezis bits and skipping over...
    NIO direct memory malloc'd size: 0.007815 MB (8195 bytes)
    [sajia@211 temp]$ time java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize `pgrep -u sajia java`
    Attaching to process ID 7381, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 20.5-b03
    NIO direct memory: (in bytes)
    reserved size = 0.000003 MB (3 bytes)
    max size = 7152.000000 MB (7499415552 bytes)

    real 0m0.401s
    user 0m0.503s
    sys 0m0.057s
    [sajia@211 temp]$ time java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize -e `pgrep -u sajia java`
    Attaching to process ID 7381, please wait...
    Debugger attached successfully.
  5. rednaxelafx revised this gist Apr 18, 2012. 2 changed files with 149 additions and 5 deletions.
    89 changes: 84 additions & 5 deletions DirectMemorySize.java
    Original file line number Diff line number Diff line change
    @@ -8,15 +8,63 @@
    import sun.jvm.hotspot.utilities.*;

    public class DirectMemorySize extends Tool {
    private boolean exactMallocMode;
    private boolean verbose;

    public DirectMemorySize(boolean exactMallocMode, boolean verbose) {
    this.exactMallocMode = exactMallocMode;
    this.verbose = verbose;
    }

    public void run() {
    // Ready to go with the database...
    try {
    long reservedMemory = getStaticLongFieldValue("java.nio.Bits", "reservedMemory");
    long directMemory = getStaticLongFieldValue("sun.misc.VM", "directMemory");

    System.out.println("NIO direct memory:");
    System.out.printf(" reserved size = %fMB (%d bytes)\n", toM(reservedMemory), reservedMemory);
    System.out.printf(" max size = %fMB (%d bytes)\n", toM(directMemory), directMemory);

    System.out.println("NIO direct memory: (in bytes)");
    System.out.printf(" reserved size = %f MB (%d bytes)\n", toM(reservedMemory), reservedMemory);
    System.out.printf(" max size = %f MB (%d bytes)\n", toM(directMemory), directMemory);

    if (verbose) {
    System.out.println("Currently allocated direct buffers:");
    }

    if (exactMallocMode || verbose) {
    final long pageSize = getStaticIntFieldValue("java.nio.Bits", "pageSize");
    ObjectHeap heap = VM.getVM().getObjectHeap();
    InstanceKlass deallocatorKlass =
    SystemDictionaryHelper.findInstanceKlass("java.nio.DirectByteBuffer$Deallocator");
    final LongField addressField = (LongField) deallocatorKlass.findField("address", "J");
    final IntField capacityField = (IntField) deallocatorKlass.findField("capacity", "I");
    final int[] countHolder = new int[1];

    heap.iterateObjectsOfKlass(new DefaultHeapVisitor() {
    public boolean doObj(Oop oop) {
    long address = addressField.getValue(oop);
    if (address == 0) return false; // this deallocator has already been run

    long capacity = capacityField.getValue(oop);
    long mallocSize = capacity + pageSize;
    countHolder[0]++;

    if (verbose) {
    System.out.printf(" 0x%016x: reservedSize = %f MB (%d bytes),"
    + " mallocSize = %f MB (%d bytes)\n",
    address, toM(capacity), capacity,
    toM(mallocSize), mallocSize);
    }

    return false;
    }
    }, deallocatorKlass, false);

    if (exactMallocMode) {
    long totalMallocSize = reservedMemory + pageSize * countHolder[0];
    System.out.printf("NIO direct memory malloc'd size: %f MB (%d bytes)\n",
    toM(totalMallocSize), totalMallocSize);
    }
    }
    } catch (AddressException e) {
    System.err.println("Error accessing address 0x"
    + Long.toHexString(e.getAddress()));
    @@ -29,6 +77,12 @@ public static long getStaticLongFieldValue(String className, String fieldName) {
    LongField field = (LongField) klass.findField(fieldName, "J");
    return field.getValue(klass);
    }

    public static int getStaticIntFieldValue(String className, String fieldName) {
    InstanceKlass klass = SystemDictionaryHelper.findInstanceKlass(className);
    IntField field = (IntField) klass.findField(fieldName, "I");
    return field.getValue(klass);
    }

    public static double toM(long value) {
    return value / (1024 * 1024.0);
    @@ -38,8 +92,33 @@ public String getName() {
    return "directMemorySize";
    }

    protected void printFlagsUsage() {
    System.out.println(" -e\tto print the actual size malloc'd");
    System.out.println(" -v\tto print verbose info of every live DirectByteBuffer allocated from Java");
    super.printFlagsUsage();
    }

    public static void main(String[] args) {
    DirectMemorySize tool = new DirectMemorySize();
    boolean exactMallocMode = false;
    boolean verbose = false;

    // argument processing logic copied from sun.jvm.hotspot.tools.JStack
    int used = 0;
    for (String arg : args) {
    if ("-e".equals(arg)) {
    exactMallocMode = true;
    used++;
    } else if ("-v".equals(arg)) {
    verbose = true;
    used++;
    }
    }

    if (used != 0) {
    args = Arrays.copyOfRange(args, used, args.length);
    }

    DirectMemorySize tool = new DirectMemorySize(exactMallocMode, verbose);
    tool.start(args);
    tool.stop();
    }
    65 changes: 65 additions & 0 deletions command_prompt2
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,65 @@
    [sajia@211 temp]$ java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize
    Usage: java directMemorySize [option] <pid>
    (to connect to a live java process)
    or java directMemorySize [option] <executable> <core>
    (to connect to a core file)
    or java directMemorySize [option] [server_id@]<remote server IP or hostname>
    (to connect to a remote debug server)

    where option must be one of:
    -e to print the actual size malloc'd
    -v to print verbose info of every live DirectByteBuffer allocated from Java
    -h | -help to print this help message
    [sajia@211 temp]$ java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize `pgrep -u sajia java`
    Attaching to process ID 7381, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 20.5-b03
    NIO direct memory: (in bytes)
    reserved size = 0.000003 MB (3 bytes)
    max size = 7152.000000 MB (7499415552 bytes)
    [sajia@211 temp]$ java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize -e `pgrep -u sajia java`
    Attaching to process ID 7381, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 20.5-b03
    NIO direct memory: (in bytes)
    reserved size = 0.000003 MB (3 bytes)
    max size = 7152.000000 MB (7499415552 bytes)
    Finding object size using Printezis bits and skipping over...
    Finding object size using Printezis bits and skipping over...
    NIO direct memory malloc'd size: 0.007815 MB (8195 bytes)
    [sajia@211 temp]$ time java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize -e `pgrep -u sajia java`
    Attaching to process ID 7381, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 20.5-b03
    NIO direct memory: (in bytes)
    reserved size = 0.000003 MB (3 bytes)
    max size = 7152.000000 MB (7499415552 bytes)
    Finding object size using Printezis bits and skipping over...
    Finding object size using Printezis bits and skipping over...
    NIO direct memory malloc'd size: 0.007815 MB (8195 bytes)

    real 0m4.822s
    user 0m2.095s
    sys 0m3.216s
    [sajia@211 temp]$ time java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize -e -v `pgrep -u sajia java`
    Attaching to process ID 7381, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 20.5-b03
    NIO direct memory: (in bytes)
    reserved size = 0.000003 MB (3 bytes)
    max size = 7152.000000 MB (7499415552 bytes)
    Currently allocated direct buffers:
    0x00002aaab021df10: reservedSize = 0.000001 MB (1 bytes), mallocSize = 0.003907 MB (4097 bytes)
    0x00002aaab0843310: reservedSize = 0.000002 MB (2 bytes), mallocSize = 0.003908 MB (4098 bytes)
    Finding object size using Printezis bits and skipping over...
    Finding object size using Printezis bits and skipping over...
    NIO direct memory malloc'd size: 0.007815 MB (8195 bytes)

    real 0m5.097s
    user 0m2.164s
    sys 0m3.426s
    [sajia@211 temp]$
  6. rednaxelafx revised this gist Mar 20, 2012. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions Notes.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    Also works on core dumps, in the form of:

    ```
    java -cp .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize $JAVA_HOME/bin/java core.xxx
    ```
  7. rednaxelafx created this gist Jan 11, 2012.
    46 changes: 46 additions & 0 deletions DirectMemorySize.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,46 @@
    import java.io.*;
    import java.util.*;
    import sun.jvm.hotspot.memory.*;
    import sun.jvm.hotspot.oops.*;
    import sun.jvm.hotspot.debugger.*;
    import sun.jvm.hotspot.runtime.*;
    import sun.jvm.hotspot.tools.*;
    import sun.jvm.hotspot.utilities.*;

    public class DirectMemorySize extends Tool {
    public void run() {
    // Ready to go with the database...
    try {
    long reservedMemory = getStaticLongFieldValue("java.nio.Bits", "reservedMemory");
    long directMemory = getStaticLongFieldValue("sun.misc.VM", "directMemory");

    System.out.println("NIO direct memory:");
    System.out.printf(" reserved size = %fMB (%d bytes)\n", toM(reservedMemory), reservedMemory);
    System.out.printf(" max size = %fMB (%d bytes)\n", toM(directMemory), directMemory);
    } catch (AddressException e) {
    System.err.println("Error accessing address 0x"
    + Long.toHexString(e.getAddress()));
    e.printStackTrace();
    }
    }

    public static long getStaticLongFieldValue(String className, String fieldName) {
    InstanceKlass klass = SystemDictionaryHelper.findInstanceKlass(className);
    LongField field = (LongField) klass.findField(fieldName, "J");
    return field.getValue(klass);
    }

    public static double toM(long value) {
    return value / (1024 * 1024.0);
    }

    public String getName() {
    return "directMemorySize";
    }

    public static void main(String[] args) {
    DirectMemorySize tool = new DirectMemorySize();
    tool.start(args);
    tool.stop();
    }
    }
    16 changes: 16 additions & 0 deletions command_prompt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    $ java -version
    java version "1.6.0_30"
    Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
    Java HotSpot(TM) 64-Bit Server VM (build 20.5-b03, mixed mode)
    $ javac -classpath $JAVA_HOME/lib/sa-jdi.jar DirectMemorySize.java
    $ jps
    18486 GroovyStarter
    23135 Jps
    $ java -classpath .:$JAVA_HOME/lib/sa-jdi.jar DirectMemorySize `pgrep java`
    Attaching to process ID 18486, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 20.5-b03
    NIO direct memory: (in bytes)
    reserved size = 0.000000 MB (0 bytes)
    max size = 4069.000000 MB (4266655744 bytes)