JVM 内存
以下图片来源于B 站,up 主ID:1126714340)
1、JVM屏蔽了不同操作系统差异,是Java平台无关性实现的基础
- 第一通过java.c,将源文件编译成class文件。
- JVM将class文件加载到内存中。
2、JVM加载class文件,内存分配具体实现。
1. 过程描述
- 一旦运行java Math.class文件,字节码就被加载到内存中。
- JVM有三部分组成(类装载子系统,运行时数据区,字节码执行引擎)。
2. 运行时数据区(内存模型)是由5部分组成(作用看Oracle的官方文档)。
2.1、堆
1、存放new出来的对象
2.2、栈(线程)
1、只要线程运行,JVM就要从大的线程栈中拿出一部分空间给该线程使用,称为线程栈。来多少个线程就分配多少线程栈。
2、线程栈的作用与组成。用来存放局部变量。一个线程栈,由多个栈帧组成。每个方法 都有自己一个专属的栈帧内存区域。
3. 分配内存称为入栈,释放内存称为出栈。先调用的方法先分配内存,后调用的方法后分配内存。但是后调用的方法先结束。先入后出
4. 栈帧的组成。首先查看字节码文件,找到class文件,右击打开终端。通过javap -c Math.class>Math.txt命令进行反汇编,生成更可读的JVM文件。
int a = 1;用下面两个语句实现。
iconst_1将int类型常量1压入栈。
istore_1:将int类型值出栈,存入局部变量1
- 动态链接。
该函数存放在方法区的代码块入口地址 - 方法出口
记录函数调用结束,需要返回的位置。程序接着运行。
2.3、本地方法栈
2.4、方法区(元空间)
2.5、程序计数器
(用来放我们正在运行或者马上运行的代码的行号或者位置,实际上放的是这行代码,存放在方法区的内存地址)。
-
程序计数器的设计初衷作用:java 程序是多线程的运行的,如果线程一刚要运行第三行的代码,来了一个优先级更高的,把CPU 时间片抢过去了,当前线程需要挂起。等cpu 切回原来线程。根据程序计数器寻找原来位置。
-
程序计数器内存分配。当线程进来,JVM和分配栈一样,从程序计数器挖一个内存给这个线程,是每个线程独有的。
3. 代码解析
第四行:将局部变量1(a)的值加载到操作数栈
第五行:将局部变量2(b)的值加载到操作数栈.
第六行:从栈顶弹出两个数,进行相加操作。得到的值 3放回栈,然后加载10到操作数栈。
4、字节码执行引擎去修改程序计数器