JVM内存模型总结

JVM内存模型
之前看过很多关于jvm内存模型的文章,什么有堆栈,方法区,程序计数器等划分,也有文章说主存和工作内存的模型。
这里我觉得无论是jvm内存区域的划分,还是主存工作内存的使用,都是属于jvm内存模型内的知识。基于自己的理解,简单总结一下,单纯只是个人总结,不一定是正确的,假如看到有错误的地方可以帮忙指出。

jvm运行期的内存区域划分:

上述图可以比较直观的看出jvm运行期,哪些内存区域属于共享的,哪些属于线程私有的。下面简单的介绍每个内存区域:
1.线程私有的内存区域:
(1)java 栈(jvm stack)
主要存放一个个栈帧,每个栈帧对应着线程执行每个方法相关的数据(局部变量表,操作栈,动态链接,方法出口等信息),每一个方法执行完了,对应的栈帧就会从java栈出栈。当栈的深度达到jvm所允许的最大深度,就会抛出 stackoverflowerror 的错误,当扩展无法申请到足够的内存则会抛出 outofmemoryerror 的错误。
(2)程序计数器(PC register)
很小的内存空间,因为jvm底层执行程序是执行字节码指令,而程序计数器就记录着当前指令的执行位置。随着指令执行而变化,从而获取下一个需要执行的指令(可实现分支,循环,跳转,异常)。
(3)本地方法栈(native method stack)
与java栈存储内容很相似,只是java栈是服务于java方法(字节码),而本地方法栈是服务于native方法。同样也会抛出上面提到的异常错误。
2.线程共享的内存区域:
(1)堆(heap)
这一块主要是存放对象数据,是jvm内存中最大的一块。包含了新生代和年老代,也是GC(垃圾回收)主要收集的区域。(GC算法会在后面的文章里提到),当内存申请超过了jvm定义的内存大小,则会报outofmemory的错误。
(2.1)本地方法区(Method Area)
主要存放的是类信息,常量,静态变量等数据,在jdk1.8之前,hotspot里是将方法区当做永久代来使用,之后废除了永久代,这里会在另外一篇文章里解释。
(2.2)运行时常量池(Runtime Constant Pool)
属于方法区的一部分,用于存放编译期生成的各种字面量和符号引用,如字符串,final变量,类名和方法名常量等(这里需要注意常量池的常量的存储大小)。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容