How to find out where exact young/old gen is located in memory?

后端 未结 2 1640
情书的邮戳
情书的邮戳 2021-01-01 02:20

Recently I was able to get an object\'s address using sun.misc.Unsafe class.

And now I am trying to find programmatically an actual generation where my object is lo

相关标签:
2条回答
  • 2021-01-01 02:41

    I don't know how to get exactly the borders of young and old generations (not even sure it's possible). In case of G1 it became even more complicated because it's allowed to have more than one old generation region due to unusual heap structure of G1.

    But you can use tricky heuristic to determine whether object is in old generation or not without knowing borders of generations.

    Let's use some black magic secret knowledge about hotspot internals: every object contains header with all necessary information about locking, identity hashcode, and most important, age. Extracting age will look like this:

    return unsafe.getByte(targetObject, 0L) & 0x78;
    

    where 0x78 is corresponding mask in object header for its age (bits from 4th to 7th inclusive).

    Obtain MaxTenuringThreshold parameter via Management API:

    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy(
                server,
                "com.sun.management:type=HotSpotDiagnostic",
                HotSpotDiagnosticMXBean.class);
    int threshold = Integer.valueOf(bean.getVMOption("MaxTenuringThreshold").getValue());
    

    Now you know object's age and tenuring threshold of your application, so you can assume that if age is greater than threshold, it's in old generation.

    WARNING: It's heuristic based on magic and secret knowledge.

    1. It will not work, if someone will synchronize on target object while you are reading it's age, because VM will move header to stack and replace header with pointer to stack
    2. It will not work with XX:+UseAdaptiveSizePolicy, so you should explicitly disable it.
    3. Some object can be allocated straight in old generation (e.g. because of it's size)
    4. Type I error prone
    5. This approach is illegal, unsafe and might be incorrect and jvm dependent
    0 讨论(0)
  • 2021-01-01 02:57

    This is possible with HotSpot JVM though somehow complicated.

    The key idea is to use VMStructs - the information about HotSpot internal constants and types embedded right into JVM shared library.

    For example, ParallelScavengeHeap::_young_gen VM global variable contains the pointer to PSYoungGen structure that has _virtual_space member with the boundaries of Parallel collector's young generation. Similarly, GenCollectedHeap::_gch global points to the structure describing CMS collector generations.

    I've made a proof-of-concept project to demonstrate the usage of VMStructs. It is pure Java, no extra libraries required, but it deeply relies on the undocumented JDK internals and may not work on all Java versions. I've tested this on JDK 8u40 and JDK 7u80 on Windows and Linux.

    • JVM.java - the code for reading VMStructs;
    • HeapInfo.java - the sample program to get addresses of Heap generations.
    0 讨论(0)
提交回复
热议问题