【深入理解JVM】JVM的内存结构(堆、栈、GC)
最近一直在看JVM相关的东西,在这里整理一下,方便以后复盘,有错误的地方欢迎留言。
Java跨平台
不同操作系统使用的指令不同,JVM屏蔽了操作系统的差异,不同JDK适应不同的操作系统,使Java具有跨平台的特性。
JVM的组成
JVM由四部分组成:
- 类加载器
- 运行时数据区
- 执行引擎
- 本地接口
运行时数据区
由 堆、栈、程序计数器、本地方法栈、方法区 五部分组成。
由线程共享
由线程独有,每个线程都包含 栈、程序计数器、本地方法栈。
栈
线程中每执行一个方法,栈中进入一个栈帧,栈帧由四部分组成。
- 局部变量表
- 操作数表
- 动态链接
- 方法出口
public class Test{
public static void main(String[] args){
int i = 1;
int j = 2;
int k = i + j;
System.out.println(k);
}
}
由Test.java说明程序运行时栈中情况。
javac Test.java 编译成Test.class。
javap -c Test.class>Test.txt 将字节码反编译结果输出到Test.txt文件中,内容如下:
Compiled from “Test.java”
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object.""????)V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: istore_3
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_3
12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
15: return
}
可以去下列网址查看 iconst_1 JVM字节码指令的含义
https://www.cnblogs.com/tenghoo/p/jvm_opcodejvm.html
大致意思:
把1放入操作数栈,将1赋给变量 i 存入局部变量,j 同理,将1和2相加为3再赋给变量k。
程序计数器会记录将要执行的指令行号,这样在挂起后恢复时就可以知道上次执行的位置。
栈帧中的动态链接
这就要说一下静态链接,在类加载过程中包含如下步骤:
静态链接在加载过程,字节码文件的符号被加载到方法区,期间需要静态链接把符号引用转为直接引用,字节码符号无法直接使用,直接引用类似于地址,这样才可以使用。
动态链接是在运行时将符号引用转为直接引用。
方法出口可以理解为方法的 return。
本地方法栈
在Java之前使用C的很多,Java有些也是用C实现的,Java中也有 native修饰的方法,这样的方法就是用C实现的,这些字符存在本地方法栈中,执行引擎会找C语言的函数库(.dll)。
执行引擎
执行引擎执行字节码的方式:
- 解释执行:一行一行边翻译边执行
- JIT即时编译执行:这里有热点代码的概念,被多次调用的方法或被多次执行的循环体视为热点代码,热点代码会被编译执行,这样效率高点
堆和Full GC
堆 由年轻代、老年代组成。在JVM启动时创建,是GC垃圾回收的主要对象,也是分配存储区最大的一块。
年轻代 由Eden区(伊甸区)、From Survivor、To Survivor组成。
这里需要说一下轻GC(Minor gc)和Full GC。
- 新创建的对象需要放入Eden区,当Eden区满后,GC回收没有被引用的对象,剩余对象放到From Survivor区;
- 当From Survivor区满后,清空From Survivor区,未被回收的对象放入To Survivor区;
- 此时From和To身份互换,From变为To,To变为From,如此循环15次(默认15次),当To区满时,将未被清理的对象放入老年代;
- 当老年代满时,触发Full GC(之前都是Minor GC),由于不同的垃圾回收器机制不同,可能把之前的区都清理,也可能只清理老年区(涉及到垃圾回收器和算法,以后再写一篇补上)。
堆、栈、方法区的爱恨纠葛
s 学生变量存在栈中,在堆中创建对象,将对象的地址赋给s变量;
堆中的对象实例指向方法区的类模板,通过类模板创建实例对象。
上一篇: 中秋吃些什么美食?中秋节有什么习俗?
下一篇: 爱自己的女人,,一定是爱喝水爱喝汤的女人
推荐阅读
-
OOM实战:堆内存溢出 虚拟机栈和本地方法栈溢出 jvm栈容量太小 栈帧太大 栈太小,导致线程分配少,创建更多的线程将导致oom 方法区和运行时常量池溢出
-
JVM内存结构学习:二、Java虚拟机堆和栈
-
【深入理解JVM】JVM的内存结构(堆、栈、GC)
-
【JVM原理与优化】Java堆空间VS栈空间 - Java中的内存分配
-
[二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义
-
深入理解JVM(三) -- 对象的内存布局和访问定位
-
荐 【探究JVM四】Java方法执行的线程内存模型——虚拟机栈 字节码指令追踪,万字长文深入探究内部结构
-
OOM实战:堆内存溢出 虚拟机栈和本地方法栈溢出 jvm栈容量太小 栈帧太大 栈太小,导致线程分配少,创建更多的线程将导致oom 方法区和运行时常量池溢出
-
Gc学习笔记:浅谈GC,简略分析CMS,Jvm堆内存结构,JVM性能调优等