查看静态变量对应的对象在是否在堆中
方法区和GC堆是不冲突的两个概念,在JVM规范中,方法区被定义为一种逻辑区域,而方法区具体怎么实现是各JVM的实现细节,所以方法区的内容在堆里也好,不在堆里也好都是符合标准的。
比如曾经HotSpot中,永久代就约等于方法区,而IBM的J9以及在Java7以后的HotSpot中就不是这样设计的;至于本题中的静态实例,目前的HotSpot是在堆中存储的。
另:如果题主有类似的疑问,又是使用的Oracle的JDK的话,可以启动sun.jvm.hotspot.HSDB(在JDK目录/lib/sa-jdi.jar里)来加载一段简单的Java代码,然后获取到你感兴趣的某一个变量oop的内存地址,工具可以查询到这个内存地址在JVM的存储位置。
实践一下:
以下操作在Oracle JDK 1.8.0_144下完成。
先编写如下代码:
public class Main {
private static String a = "test";
private static Main b = new Main();
public static void main(String... args) {
}
}
存在两个静态变量,一个字符串,一个Main,运行时使用HSDB连接这个运行中的虚拟机,得到两个oop的地址:
查看确实是那个字符串和Main:
再进一步查看他们的位置:
可见两个静态变量都在Java堆中。