文章目录
一、java中的JVM整体结构与内存模型
1.1、JVM整体结构
其主要分为三部分组成,分别是类加载子系统、运行时数据区、字节码执行引擎,如下图:
1.2、JVM内存模型
这里主要介绍JVM运行时数据区的内存模型,具体内存区域分为:堆、栈、本地方法栈、方法区、程序计数器,介绍如下:
1.2.1 JVM内存模型—栈(线程栈)
栈区域中主要是存放:局部变量、操作数栈、动态连接、方法出口,线程中的每个方法都会分配出一个栈帧,具体各自的介绍如下图示:
我们这结合实际的代码以及class文件的反编译结果来对栈中存储的数据进行剖析,首先是add方法中,有三个变量,以变量a为例,首先会在栈中的局部变量表分配内存给a,再将a的值加载到操作数栈,并且将值赋值给a,b也是一样,c的值其实是先加载a和b的值到操作数栈,在操作数栈调CPU进行运算,运算完毕之后再return;
还要一个是方法出口,我们再main方法中调add方法,那调完之后是需要回到main方法中的,这时候需要存储这个方法执行完毕之后,应该是从哪回到主线程中;
其次是动态连接,mian方法中,我们可以看到有一行代码是jt.add(),这行代码是需要在程序运行时,才会将这些符号变为实际的地址值,那这种情况我们就称位动态连接;
最后一个是main方法中,有一个new JvmTest()的操作,我们new的对象都是需要存到堆中的,所以这时候在栈中的jt符号是指向堆中这个对象的具体地址信息;
每个线程中的,栈、程序计数器、本地方法栈都是当前线程独有的,而堆和方法区的每个线程都可以访问的内存区域
1.2.2 JVM内存模型—堆
栈区域中主要是存放:对象的,主要的区域分为老年代和新生代(jdk1.8),具体各自的介绍如下图示:
字节码执行引擎在运行程序时,如果需要gc时,也是会和对产生STW交互的,对象创建时,一般会放到Eden区,GC时如果没别回收,就会在S0区与S1区进行切换存储,每切换一次代年龄会+1,默认加到15时,会移到老年代中去
1.2.3 JVM内存模型—程序计数器
这个区域主要是记录字节码执行引擎执行到当前位置信息
1.2.4 JVM内存模型—本地方法栈
这个区域主要是存储被Native修饰的方法数据
1.2.4 JVM内存模型—方法区
这个区域主要是存储类元信息,静态变量和常量,有些静态变量是对象形式,所以这里也会有部分与堆有交互