天天看点

【深入理解JVM】JVM的内存结构(堆、栈、GC)Java跨平台什么是JVM?JVM的组成运行时数据区

文章目录

  • Java跨平台
  • 什么是JVM?
  • JVM的组成
  • 运行时数据区
      • 栈帧中的动态链接
    • 本地方法栈
    • 执行引擎
    • 堆和Full GC
    • 堆、栈、方法区的爱恨纠葛

  最近一直在看JVM相关的东西,在这里整理一下,方便以后复盘,有错误的地方欢迎留言。

Java跨平台

  不同操作系统使用的指令不同,JVM 可以将字节码翻译成特定平台下的机器码运行,在不同平台安装对应的 JVM,就可以运行字节码,通过 JVM 这一“中间层”屏蔽了操作系统的差异,不同 JDK 适应不同的操作系统,使Java具有跨平台的特性。

什么是JVM?

   JVM 即 Java Virtual Machine(Java虚拟机) , 模拟一个计算机来达到计算机所具有的计算功能。屏蔽各计算机硬件和软件之间的差异,使字节码文件可以“到处运行”。

JVM的组成

JVM由四部分组成:

  • 类加载器
  • 运行时数据区
  • 执行引擎
  • 本地接口

运行时数据区

   由 堆、栈、程序计数器、本地方法栈、方法区 五部分组成。

【深入理解JVM】JVM的内存结构(堆、栈、GC)Java跨平台什么是JVM?JVM的组成运行时数据区
【深入理解JVM】JVM的内存结构(堆、栈、GC)Java跨平台什么是JVM?JVM的组成运行时数据区

由线程共享

【深入理解JVM】JVM的内存结构(堆、栈、GC)Java跨平台什么是JVM?JVM的组成运行时数据区

由线程独有,每个线程都包含 栈、程序计数器、本地方法栈。

【深入理解JVM】JVM的内存结构(堆、栈、GC)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。

  程序计数器会记录将要执行的指令行号,这样在挂起后恢复等操作时就可以知道上次执行的位置。

栈帧中的动态链接

这就要说一下静态链接,在类加载过程中包含如下步骤:

【深入理解JVM】JVM的内存结构(堆、栈、GC)Java跨平台什么是JVM?JVM的组成运行时数据区

  静态链接在类加载过程中的解析阶段进行,将部分符号引用转为直接引用,字节码符号无法直接使用,直接引用类似于地址,这样才可以使用。

  动态链接是在运行时将符号引用转为直接引用。

  方法出口可以理解为方法的 return。

本地方法栈

  在Java之前使用C的很多,Java有些也是用C实现的,Java中也有 native修饰的方法,这样的方法就是用C实现的,这些字符存在本地方法栈中,执行引擎会找C语言的函数库(.dll)。

执行引擎

执行引擎执行字节码的方式:

  • 解释执行:一行一行边翻译边执行
  • JIT即时编译执行:这里有热点代码的概念,被多次调用的方法或被多次执行的循环体视为热点代码,热点代码会被编译执行,这样效率高点

堆和Full GC

【深入理解JVM】JVM的内存结构(堆、栈、GC)Java跨平台什么是JVM?JVM的组成运行时数据区

堆 由年轻代、老年代组成。在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),由于不同的垃圾回收器机制不同,可能把之前的区都清理,也可能只清理老年区(涉及到垃圾回收器和算法,以后再写一篇补上)。

堆、栈、方法区的爱恨纠葛

【深入理解JVM】JVM的内存结构(堆、栈、GC)Java跨平台什么是JVM?JVM的组成运行时数据区

   s 学生变量存在栈中,在堆中创建对象,将对象的地址赋给s变量;

堆中的对象实例指向方法区的类模板,通过类模板创建实例对象。

下一篇: 从大到小

继续阅读