JVM内存结构图
大家好,好几天没有更新了,今天的内容有点多,我们详细介绍下JVM内部结构图,还是和之前一样, 案例先行,方便大家理解记忆。
如上代码:在主线程中for循环新建2个线程调用sayHello,最后两个线程分别对世界问好!这段代码比较好理解,就不贴输出结果了。我们编写并运行了这段代码,我们主要看看这段代码在JVM中是怎么运作的。
首先,我们编写一个HelloWorldTest.Java文件, 经过javac编译会转化成字节码 HelloWorldTest.class,为什么要转化成字节码呢?因为Java虚拟机能识别!最后由类加载子系统ClassLoader将字节码装载到内存。每块内存各有自己的作用,最后由执行引擎来执行字节码。下面我们重点介绍下各块内存发挥的作用!
方法区
方法区主要装一些静态信息,比如:类元数据,常量池,方法信息,类变量等。如上代码HelloWorldTest.class是类元数据,sayHello,main都是方法信息等都是放在方法区存储的。方法区中还需要注意两点:
堆中主要存放实例对象。你可以这么理解,只要看到用关键字 new的对象,数据都放在堆中。如上代码HelloWorldTest helloWorldTest = new HelloWorldTest();helloWorldTest是HelloWorldTest对象的引用,指向new出来的HelloWorldTest对象实例,helloWorldTest引用是放在栈中的,也叫 局部变量( 方法内申明的对象类型或普通类型),我们简单画图来表示下 堆,栈,方法区关系。当JVM执行了HelloWorldTest helloWorldTest = new HelloWorldTest();这句话,JVM内存结构看起来是这样的。如果指向对象引用消失,对象会被GC回收。
在堆内存中,内存需要划分成两块区域, 新生代和 老年代。如下图所示。
对堆分块原因是方便JVM 自动处理垃圾回收。 堆内存是GC回收的主要区域。
栈内存空间相对于堆空间比较小,也属于线程私有,栈中主要是一堆栈帧,是先进后出的,理解起来栈帧对应就是一个方法,方法中包含局部变量,方法参数,还有方法出口,访问常量指针,和异常信息表,其中异常信息表和常量指针信息我们在方法体中可能看不出来,但通过工具 Jclasslib工具类在反编译class文件可以体现出来,异常信息表可以处理当程序执行报错,会跳转到具体哪行代码执行,JVM中就是通过异常表反馈的。我们还是结合例子和图来详细分析下。当程序运行时,JVM中栈可能如下图呈现状态。