了解 JVM和JVM内存结构(JVM运行时数据区)
Posted XeonYu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了了解 JVM和JVM内存结构(JVM运行时数据区)相关的知识,希望对你有一定的参考价值。
JVM
官方参考文档:
https://docs.oracle.com/javase/specs/jvms/se16/html/index.html
首先,JVM就是 Java虚拟机,是一个抽象的计算机,可以通过指令集去操作不同的内存区域。
我们所编写的Java程序最终就是编译成 .class 字节码文件运行在Java虚拟机中的。
我们都知道 Java语言的一大特性就是跨平台。原因就是JVM可以在不同的操作系统中运行,而我们的程序是在JVM中运行的,所以,自然而然的我们的程序也就可以跨平台了。
大致执行过程如下:
我们可以写个简单的例子看一下:
随便写一个简单的类,如下
public class YZQ {
public static void main(String[] args) {
String name = "yzq";
name = "Xeon";
System.out.println("name = " + name);
}
}
下面我们来用命令编译一下,然后运行看看
首先简单说一下后面用到的命令:
- javac 文件名.java : 是将java文件编译成class文件
- java 文件名(class文件) :运行文件
- javap -c 文件名(class文件):反汇编class文件,就是把class文件转成我们能看懂的指令
更多的命令去官方文档看:
https://docs.oracle.com/en/java/javase/16/docs/specs/man/index.html
操作步骤如下:
如图所示,我们先通过javac 文件名.java
将YZQ.java文件编译,编译结束后就多了一个class
文件。
然后通过java class文件名
命令就可以运行了。
我们来看一下class文件是啥样的。
如图所示,class文件里面都是16进制的数据。这玩意我们肯定看不懂,下面我们反汇编看看是什么样的。
javap -c 文件名
可以看到,我们的程序实际上就是一步一步执行的,至于这些指令的含义是什么,看官方文档即可。
https://docs.oracle.com/javase/specs/jvms/se16/html/jvms-2.html#jvms-2.11
这里我们就不深究了,我们这里只需要知道从Java代码到JVM运行这个过程是什么样的就可以。
了解完Java代码运行的流程之后,我们来看看JVM的组成部分
如图所示,主要有以下5个组成部分
组成部分 | 作用 |
---|---|
类加载器 (Class Loader) | 加载字节码文件到内存(运行时数据区)中 |
运行时数据区 (Runtime Data Area) | 是JVM核心的内存控件结构模型 |
执行引擎(Execution Engine) | 也叫做命令解释器,将字节码文件翻译成操作系统认识的指令集去运行 |
本地方法接口 (Native Methord Interface) | Java语言和其他语言(一般是c或c++)相互调用的一种协议 |
本地方法库 | Java本地方法的具体实现 |
而我们常说的JVM内存结构,就是指JVM的运行时区域
JVM 内存结构
上面也说了,JVM 内存结构实际上就是JVM中的运行时数据区,是JVM程序在操作系统上运行时分配的内存区域。
运行时数据区主要分为5个部分,如下图
组成部分 | 作用 |
---|---|
方法区 | 线程共享,主要用来存放类信息、常量、静态变量等数据 |
堆 | 线程共享,主要用来存放对象及对应的实例变量和数组等数据,占用空间较大,是GC主要管理的区域 |
虚拟机栈 | 线程私有,存放的是栈帧,每个栈帧对应一个方法 |
程序计数器 | 线程私有,用来记录当前线程执行的指令行号 |
本地方法栈 | 线程私有 存储本地方法相关的信息 |
需要注意的是:
方法区和堆是线程共享的
虚拟机栈和程序计数器以及本地方法栈是线程私有的
如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!
以上是关于了解 JVM和JVM内存结构(JVM运行时数据区)的主要内容,如果未能解决你的问题,请参考以下文章