实战「静态变量」「实例变量」「局部变量」

这篇文章就以实战的方式看看「静态变量」「实例变量」「局部变量」存放的位置!

首先要搞清楚一个概念,「静态变量」「实例变量」「局部变量」指的是引用本身,而非它们所指向的对象,它们所指向的对象毫无疑问肯定都存放在堆上,关于这个观点更多分析可见 逃逸分析

还需要强调一个点,这里是基于 JDK8 的 HotSpot 虚拟机!!

根据理论知识可以知道:「静态变量」在 JDK7 及以后就存放在 Java 堆中;「实例变量」随着对象实例存放在 Java 堆中;「局部变量」存放在方法栈帧的局部变量表中

首先给出一段测试代码:

我们先分析一下,按照理论来说,此时 Java 堆中肯定存在 3 个ObjectHolder对象实例,同时staticObjinstanceObj也都在 Java 堆中

下面通过 VisualVM + JProfiler 软件测试一下!!首先用 VisualVM 保存一个 Java 堆的 dump文件,如下所示:

100

用 JProfiler 打开这个 dump 文件,可以发现在 Java 堆中刚好有 3 个ObjectHolder对象实例,如下图所示:

101

我们再找找「静态变量」在哪里,在java.lang.Class中可以发现我们定义的静态变量staticObj,而这个静态变量指向的对象实例是0xa87,如下图所示:

102

继续找「实例变量」在哪里,在com.lfool.myself.Test$Person中可以发现我们定义的实例变量instanceObj,而这个实例变量指向的对象实例是0xc3b,如下图所示:

103

到此为止,我们找出来的所有内容都存放在 Java 堆中,至于「局部变量」,可以通过 JHSDB 软件在栈中发现,这里就不演示了!!!