long龙8国际中文网

一个关于 编程问题的解答网站.

有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何找出确切的年轻人/老年人在内存中的位置?

最近,我使用sun获得了一个对象的地址。杂项。不安全的班级

现在我正试图通过编程找到我的对象所在的实际代。为此,我想知道每一代人的起点和终点。 Java(Oracle JVM)是否提供了解决此问题的工具?我认为不会,因为即使是不同的GCs也需要不同的内存结构(例如G1),这使得任务更加有趣:)

我想知道的只是几个代表记忆中几代人边界的数字,比如:

   young gen: start point - 8501702198   
              end point   - 9601256348

我很想听听你最疯狂的关于一种黑魔法的想法,这种魔法可以确定不同的世代区域在记忆中的位置


共 (1) 个答案

  1. 黑魔法秘密知识:每个对象都包含有关于锁定、身份哈希码和最重要的年龄的所有必要信息的标题。 提取年龄将如下所示:

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

    其中0x78是对象头中与其年龄对应的掩码(包括第4位到第7位)

    通过获取MaxTenuringThreshold参数:

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

    现在您知道了对象的年龄和应用程序的使用期限阈值,所以您可以假设,如果年龄大于阈值,则是在旧一代

    警告: 这是基于魔法和秘密知识的启发

    1. 如果有人在您读取目标对象的年龄时对其进行同步,那么它将不起作用,因为VM会将头移动到堆栈,并用指向堆栈的指针替换头
    2. 它不能与XX:+UseAdaptiveSizePolicy一起使用,所以应该显式禁用它
    3. 在旧一代中,某些对象可以直接分配(例如,因为它的大小)
    4. 这种方法是非法的、不安全的,可能是不正确的,并且依赖于jvm