乐趣区

2JVM内存结构


一、JVM 由字节码执行引擎、类装载子系统、运行时数据区组成。

1. 类装载子系统次要是把 class 文件加载到运行时数据区中,

2. 字节码执行引擎次要是执行字节码文件,并把执行的相应的行数数据推送到运行时数据区中的程序计数器中

3. 运行时数据区是文件执行的次要场合。

二、运行时数据区由上面几个区域形成:

1. 堆:大多数对象创立之后都放在堆中,多数放在栈中

2. 栈:每个线程产生都会有一个独有的线程栈(在栈上分的一小块内存),栈的次要作用是为程序运行提供场合,即程序的执行操作在栈中进行

3. 本地办法栈:寄存一些执行本地办法的地址指针,次要是一些晚期的 c ++ 执行的本地办法

4. 程序计数器:记录程序运行的地位,如果被打断之后能够接着打断的中央接着运行

5. 办法区(元空间):寄存一些动态变量、类元信息等

元空间和堆是所有执行文件所共享的区域,即一个动态变量被创立之后能够被另一个线程所援用

而每一个线程都有本人的其余区域,即线程栈、程序计数器和本地办法栈,线程完结后即被销毁

三、别离介绍:

1. 堆(垃圾回收机制):堆分为年老代和老年代,空间大小为 1:2,年老代又分为 eden 区和 survivor 区,比例为 8:1:1,以上两个比例皆能够批改
对象在被创立后放入 Eden 区中,当 Eden 区放满之后,会进行一次 minor gc, 通过可达性算法剖析,将垃圾对象进行回收,而后将不是垃圾的对象放入 survivor1 区中,通过程序执行之后,如果 eden 区再次放满,则会将 Eden 区和 survivor1 区中的对象进行垃圾回收,将依然存活的对象放入 survivor2 区中,即每次进行垃圾回收后的对象都放在另一个 survivor 区中,直到对象的分带年龄达到设定值之后(默认为 15,因为对象中的分代年龄指针占四个字节,最大值为 15),放入老年代,其中,对象每经验一次 minor gc,分代年龄就会加一。老年代通过屡次 minor gc 后,也会放满,如果老年代放满,程序会进行 full gc,即,程序会进行 STW(stop the),即终止程序运行,而后通过可达性剖析算法,进行一次 full gc。如果对象依然存活,则持续寄存在老年代中,如果老年代的对象 full gc 之后依然满了,则会呈现内存溢出的谬误状况。

2. 栈:

栈是程序运行的次要场合,每有一个线程运行时,jvm 就会给这个线程在栈上调配一块独立的区域(线程栈)去寄存本人的局部变量,线程栈的次要由栈帧组成,每个办法都有一个独立的栈帧,栈帧上次要有:办法进口、动静链接、操作数栈、局部变量表组成。比方执行 main 办法,则 main 办法有本人独立的栈和本地办法栈以及程序计数器,依据程序计数器,来进行记录执行的地位,通过字节码执行引擎进行执行,执行 main 办法时,会给 main 办法生成一个独立的栈帧,栈帧中本地变量区域放入办法中生成的局部变量,对局部变量进行操作时,将局部变量放入操作数栈中(局部变量做操作时用来直达寄存的内存空间),当执行操作时,将操作数栈中的数据程序出栈,放入内部寄存器中,用运算器进行运算,运算进去后果之后再把值放入操作数栈中,再进行赋值给本地变量。动静链接:程序在加载时,在解析阶段只会进行动态链接(将符号援用替换为间接援用,该阶段会把一些静态方法 (符号援用,比方 main() 办法)替换为指向数据所存内存的指针或句柄等(间接援用),这是所谓的动态链接过程(类加载期间实现),动静链接是在程序运行期间实现的将符号援用替换为间接援用,下节课会讲到动静链接),即只解析静态方法,当程序运行到静态方法中的一般办法时,会进行动静链接。因为程序在加载阶段会把编译为一条条指令文件,而后寄存在元空间的常量池中,所以在执行动静链接时,便是找到该办法的在元空间常量池的地址。办法进口:一个办法运行实现之后返回到下层调用办法的哪一个地位。如果办法中援用对象信息,则对应点局部变量表中保留的是堆中对象的地址指针。

3. 程序计数器:
记录程序运行的地位,如果程序暂停,再从新开始后,程序会从程序计数器的地位开始执行,程序计数器的地位是内部字节码执行引擎执行发送的地址。

4. 本地办法栈:
寄存一些本地底层的办法。

5. 办法区(元空间):
寄存动态变量、字符串常量池、对象常量池、类元信息等。动态变量:文件在加载过程中,在筹备阶段对一些动态变量进行调配空间,并赋予默认值,在初始化阶段再进行赋初始值。常量池:寄存相应信息。类元信息:文件在加载过程中,在加载阶段,文件会编译为字节码文件,其中,相应的类中的办法、变量等相应的信息为类元信息。动态变量是对象类型,则寄存指向该对象在堆中的地址。

四、相互之间的分割:

通过类装载子系统进行装载类,而后通过字节码执行引擎进行执行,执行 main()办法时,在栈中划分一小部分空间生成线程栈,在线程栈中为 main 办法生成独立栈帧,如果类中有其余办法,则生成一个新的栈帧,在栈帧中的局部变量表中寄存执行过程中的局部变量,在操作数栈中进行对操作数进栈以及出栈,而后在内部执行运算,在赋值给本地变量,其中执行步骤都是由该线程独有的程序计数器计数执行地位供字节码执行引擎执行。如果栈帧中局部变量为对象类型,则局部变量表中寄存的是堆中对象的指针地址。该对象头中存在指针,指向其所属的类,也就是指向办法区中该类的地址。当一个类加载到 jvm 中会产生类对象,即在堆中寄存的 class 对象,办法区中的类元信息会再次指向堆中的 class 类对象。

如果办法区(元空间)中动态变量是对象类型,则办法区(元空间)的常量池中寄存指向该对象在堆中的地址。

退出移动版