You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDK17下用JHSDB定位静态变量位置不符预期,求技术指导

JDK17下JHSDB未找到堆中静态变量staticObj的原因及解决办法

问题重现

运行以下Java代码后,按书籍步骤用JHSDB调试,未在堆中找到预期的staticObj静态变量:

package chapter9;

public class JHSDBTest {
    static class Test{
        static ObjectHolder staticObj = new ObjectHolder();
        ObjectHolder instanceObj = new ObjectHolder();

        void foo(){
            ObjectHolder localObj = new ObjectHolder();
            //debug
            System.out.println("done");

        }
    }
    private static class ObjectHolder{}

    public static void main(String[] args) {
       Test test =  new JHSDBTest.Test();
       test.foo();
    }
}

已知JDK7后静态变量移出永久代,JDK8起元空间替代永久代,静态变量存于堆中,但JDK17环境下未找到目标对象,且已配置VM参数。

可能的原因及解决步骤

1. 查找方式错误:静态变量是类对象的一部分

JDK8+中,静态变量确实存在堆中,但它是作为Test类的Class对象的字段存储的,并非独立的顶级对象。你不能直接搜索staticObj这个对象,而要先找到Test的Class实例,再查看其字段引用的ObjectHolder对象:

  • 用jps获取进程ID,启动jhsdb hsdb --pid <进程ID>
  • 打开Tools -> Class Browser,定位到chapter9.JHSDBTest$Test类
  • 查看类的静态字段列表,找到staticObj对应的对象地址
  • 用Tools -> Inspector输入该地址,即可看到对应的ObjectHolder实例,确认其在堆中

2. 对象被提前GC回收

如果程序运行过快,在你连接JHSDB前,对象可能被GC回收(虽然静态变量关联的类对象默认不会被轻易卸载,但极端情况可能发生):

  • 修改foo()方法,添加延迟让程序挂起:
    void foo(){
        ObjectHolder localObj = new ObjectHolder();
        System.out.println("done");
        try {
            Thread.sleep(100000); // 挂起100秒,留足调试时间
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
  • 确保JHSDB连接时,程序处于运行状态,未进入退出流程

3. VM参数干扰

检查你配置的VM参数,是否存在影响类加载或堆内存的设置:

  • 确保添加了JHSDB调试必需的参数:-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints
  • 暂时移除自定义的GC参数或内存参数,用默认配置测试,排除参数干扰
  • 若开启了-XX:+ClassUnloadingWithConcurrentMark等类卸载参数,可能导致Test类被提前卸载,静态变量引用的对象也会被回收,建议关闭这类参数后重试

4. 对JHSDB工具的使用误解

部分旧书籍的JHSDB操作步骤可能基于低版本JDK,JDK17的JHSDB界面或命令有变化:

  • 避免用旧的find命令直接搜索对象,改用scanoop命令查找chapter9.JHSDBTest$ObjectHolder类型的所有实例,再结合类对象的字段引用判断哪个是staticObj
  • 示例命令(在JHSDB的CLI模式下):
    scanoop chapter9.JHSDBTest$ObjectHolder
    
    会列出所有ObjectHolder实例的地址,再通过inspectheap查看每个地址的归属,找到属于Test类静态字段的那个实例

内容的提问来源于stack exchange,提问作者竹玄羽

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 12:03:21