JVM内存模型
2023-07-13 22:35:13 0 举报
还在制作中
作者其他创作
大纲/内容
Method_3
动态链接(Dynamic Linking)
线程共享
a:1
LIFO
线程私有
栈帧(Stack Frame)
类元信息
8种基本类型
如果被调用的方法带有返回值的话,其返回值将会被压入当前栈帧的操作数栈中,并更新PC寄存器中下一条需要执行的字节码指令
溢出问题
数组 array_1
文本字符串
类加载器的引用
...
对象 Object_1
每个类结构
程序计数器/PC寄存器(线程私有)
PC寄存器
对象 Object_2
本地方法栈 Native Method Stacks(线程私有)
老年代伸缩区 virtual
对象 Object_n
方法信息
栈底
out
域信息
Native Method Stack 里等级native的方法,在Execution Engine 执行时加载本地方法库如果线程请求分配的栈容量超过本地方法栈允许的最大容量,Java虚拟机将会抛出一个StackOverflowError异常如果本地方法栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的本地方法栈,那么Java虚拟机将会抛出一个OutOfMemeryError异常
字段名称和描述符
伊甸区 Eden(8/10)
字面量
TLAB_n
Operand Stack
Survivor区与Eden区同样属于年轻代,Survivor区有两块区域from/S0区和to/S1区,这两块区域是相对的,当发生一次MinorGC后,from区会和to区对换。在发生MinorGC时,Eden区和from区会将一些仍在存活的对象复制到to区,并清除内存,而to区会把一些存活的足够久的旧对象放入老年代。
Java虚拟机规范允许Java栈的大小是动态的或者固定不变的。font color=\"#e74f4c\
堆用来存放对象,几乎所有(逃逸分析技术、栈上分配、标量替换)的对象都在堆上分配,将堆作细致的内存分配是为了更快的分配内存、更好的回收垃圾。当堆中的没有内存用于分配对象,并且无法伸缩扩展时,就会抛出OOM异常
Survivor1/S1/To(1/10)
局部变量表(Local Variable Table)
堆 Heap
程序计数器:当前线程所执行的字节码的行号指示器。字节码解释器工作时,通过改变计数器的值,执行下一条指令;此内存是JVM规范中唯一一个没有OOM的区域
Eden区属于堆的年轻代,是new 对象分配内存的地方;由于堆是所有线程共享的,所以堆上的内存是需要加锁的,为了提高效率,会为每个新建的线程在Eden区上分配一块独立的空间并由该线程独享,这块空间简称TLAB(Thread Local Allocation Buffer)。在TLAB上分配内存不需要加锁,因此JVM给线程中的对象分配内存时会尽量在TLAB中分配。如果对象太大或者TLAB空间不足了。仍然在堆中分配,如果Eden区也空间不足了,则触发一次MinorGC(young GC)
in
基本数据类型值
栈 Stack (线程私有)
Survivor0/S0/From(1/10)
直接内存 Direct Memory
正常调用完成异常调用完成
栈顶缓存技术 Top-of-Stack Cashing
运行时常量池 Runtime Constant Pool
reference类型
类实例的引用
复制算法来回交换
方法区 Method Area / 元空间 MetaData Space / Non-Heap (JDK1.8)
局部变量表中的变量也是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象都不会被回收
Todo
Method_1
符号引用
DM不是虚拟机运行时数据区的一部分,也不是《java虚拟机规范》中定义的内存区域,但这部分内存也会被频繁使用,而且也可能导致OOM异常出现。如NIO中的DirectByteBuffer就会直接操作堆外内存。
方法表
TLAB_2
方法返回地址(Return Address)
数组 array_n
本地接口
老年代 Old Gen(2/3)
age15 / 大对象
String 字符串常量池
Method_2
类型信息
运行时数据区 Runtime Data Area (单例)
操作数栈(Operand Stack)
当某一个线程调用本地方法时,它就进入了一个全新的并且不再受虚拟机控制的世界,它和虚拟机拥有同样的权限
年轻代伸缩区 virtual
本地方法库
新生代/新生区/年轻代 Young Generation Space(1/3)
ref
即时编译器(JIT)编译的代码缓存
final常量值
方法名称和描述符
类和结构的全限定名
b:2
Method_N
局部变量槽-Slot,32位以内的数据类型只占用一个slot(包括returnAddress类型),64位的类型(long、 double)占用两个slot
return address
TLAB_1 (线程私有)
CPU
无论哪种方式退出,在方法退出后都返回到该方法调用的位置,方法正常退出时,调用者pc计数器的值作为返回地址,即调用该方法的指令的下一套指令的地址。而异常退出,返回地址是要通过异常表来确定,栈帧中一般不会保存这部分信息。通过异常完成出口退出的不会给他的上层调用者产生任何的返回值
span style=\
执行引擎
额外信息,如调试信息等
解释执行状态下,将访问最频繁地数据(栈顶元素、程序计数器)全部缓存在物理CPU的寄存器中,以此降低对内存的读/写次数,提升执行引擎的执行效率
栈顶
其他信息
0 条评论
下一页