动手画图理解Java虚拟机运行时的数据区域问题

写在前面

信息高速时代如何界定一名优秀的人才呢?决定一个人是否优秀的最重要因素就是他的思维方式。在阅读的时候思维方式活跃,读书就会卓有成效;在写作的时候思维质量高,写出的文字就会吸引读者。优秀的人总是在思考和关注他们的思维过程,不断地对其进行反省和调整。

正文

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,比较笼统地划分为堆内存(Heap)和栈内存(Stack),我们用一个代码实例及对应的图像解析进行说明。

代码实例
/**
 * JVM--类的加载过程
 *
 * @author zhuhuix
 * @date 2020-05-15
 */
public class ClassLoader {
    public static ClassLoader instance = new ClassLoader();
    private int a;
    private static int b = 1;

    public ClassLoader() {
        a++;
        System.out.println("a:"+a+"," +"b:"+b++);
    }

    public static void main(String[] args) {
        ClassLoader c1 = new ClassLoader();
        ClassLoader c2 = new ClassLoader();

        System.out.println(instance.hashCode());
        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
    }

}

代码中主要存在以下信息:

  • ClassLoader 类
  • main主方法
  • ClassLoader构造函数方法
  • instance ,c1,c2对象实例
  • 局部变量a
  • 静态变量b
图像解析

按JAVA虚拟机规范的要求:

  • 类信息和静态常量由方法区负责存储
  • 对象实例由堆内存负责存储
  • 方法和局部变量由栈帧进行存储
    我们可以得到如下图形:
    在这里插入图片描述
代码解析

这里我们主要看一下变量a和b的值

  • 代码中总共有三处new了ClassLoader对象,即在堆内存中存储了三个实例对象。按类加载的过程,在栈内存中分配了三个栈桢,由于a是实例对象的局部变量,所以出现在栈桢中。也就创建对象加载类的构造方法时,三个栈桢中的局部变量都由初化值0变为1;
  • 由于b是静态变量,所以b出现在方法区,也即线程共享区域内。即程序new三个对象时,都会触发b变量的变化。
  • 在给对象instance进行分配内存时,由了b还没有进行赋值为1。即该对象对应的构造方法中的输出为b=1,而a变量为局部变量,该对象输出的值都为a的初始值加1,即a=1
    在这里插入图片描述
  • 在main方法中创建对象c1,c2触发对象对应的构造方法时,静态变量b已经赋值为1,所以陆续输出为b=1,b=2;而a变量为局部变量,这两个对象输出的值都为a的初始值加1,即a=1
    在这里插入图片描述
    以下为程序实际输出值 :
    在这里插入图片描述

写在后面

理清逻辑就是清晰高效地思考问题。对于JAVA虚拟机的理解,除了对书本上的知识要理解之外,希望大家一定要动起手来画一些图,融汇贯通才能体会到真谛。

原创文章 56 获赞 8 访问量 4713

猜你喜欢

转载自blog.csdn.net/jpgzhu/article/details/106139737
今日推荐