1. jvm内存模型图解

jvm主要分为三大块,内装载子系统,运行时数据区,执行引擎,本文主要讲述运行时数据区的组成部分及各部分的作用
2. 运行时数据区(jvm内存模型)的组成
jvm内存模型讲的就是运行时数据区,运行时数据区由5部分组成,分别是堆(heap),栈(stack),元空间(Meta space1.7之前叫方法区),本地方法栈(Native Method Stack),程序计数器(Program Counter)
2.1 堆
堆内存存放java对象,比如我们new出来的对象一般会放在堆中,堆内存可以继续划分,下图中对堆内存继续分析

堆内存分为年轻代和老年代,新对象一般会放到年轻代的Eden区,
堆内存是线程共享的
堆内存在垃圾回收还会详细讲
2.2 栈
栈图解

线程栈,一种FIFO的数据结构,程序启动,会先开辟main线程的栈帧,在main方法中调用其他方法,会将新的栈帧压入栈。每个方法对应一块栈帧,当方法调用完之后,该方法对应的栈帧弹出栈。
在方法对应的栈帧中,分为四块,分别是局部变量表,操作数栈,动态链接,方法出口。局部变量表存当前方法对应的局部变量,操作数栈存储当前操作的数据。动态链接与静态链接区分,jvm在类加载的时候会把静态链接替换成对应的引用地址,动态链接就是在jvm运行的时候动态替换成引用地址。方法出口,就是该方法何时运行结束
栈内存是线程独有的
3. 元空间
jdk1.8代替了之前的方法区(永久代)
方法区存储着静态变量,常量池,以及类的元数据,方法区是线程共享的
在1.8移除了方法区,取而代之的是元空间,元空间本质上与方法区类似,最大的区别在于方法区本质上属于堆内存的一部分,为了与堆区别,称之为非堆,所使用的是虚拟机内存,这样的方法区会造成OOM(内存泄漏),元空间是与堆完全区别的概念,它使用的是本地内存(机器的物理内存),元空间理论上是可以无限大的(最大不能超过本地内存),因此基本不会造成内存泄露问题。我们可以通过
-XX:MetaspaceSize=xx和-XX:MetaMaxspaceSize=xx设置元空间的初始值和最大值,元空间是会发生full gc的,但是full gc回收的量会很少,如果不配置这两个参数name虚拟机默认初始值约21M,并且动态扩容和减少,-XX:MetaMaxspaceSize=-1,无穷大。
有时候启动程序很慢,就是因为元空间太小,每次满了之后出发full gc,触发的次数很多,所以程序启动会很慢,可以适当调大元空间初始值,一般对于8G的物理机来说,-XX:MetaspaceSize和-XX:MetaMaxspaceSize都设置为256M比较合适
4. 程序计数器
程序计数器受cup控制,记录下代码执行的行数,当线程继续执行的时候从记录的行数继续执行
5. 本地方法栈
存储着程序用到的native方法,native方法是物理机的本地方法,一般是由c/c++实现
本文深入探讨JVM内存模型,重点解析运行时数据区的构成,包括堆、栈、元空间、程序计数器和本地方法栈。堆内存分为年轻代和老年代,用于存储Java对象;栈则按线程分配,每个方法对应一个栈帧,存储局部变量和操作数据。元空间在JDK1.8中取代了方法区,使用本地内存,避免了内存泄露问题。程序计数器记录代码执行位置,本地方法栈存储native方法。了解这些内存区域有助于优化JVM性能和解决内存相关问题。
1088

被折叠的 条评论
为什么被折叠?



