jvm内存模型和运行时数据区(jvm内存模型的区别)

jvm内存模型和运行时数据区(jvm内存模型的区别)本文研究了 java8 的内存模型 此外还包括内存相关参数配置 新生代 老生代 永久代 元空间 GC 收集器这些概念你想了解吗 根据 java8 的 JVM 规范 JVM 内存分为 1 VM Stacks 虚拟机栈 每个线程都有一个私有的栈 栈帧 每个方法都有个栈帧 里面存放了局部变量表 操作数栈 方法出口等信息 2 Native Method Stack 本地方法栈

大家好,我是讯享网,很高兴认识大家。



本文研究了java8的内存模型,此外还包括内存相关参数配置.

新生代/老生代/永久代/元空间/GC/收集器这些概念你想了解吗?

根据java8的JVM规范,JVM内存分为:

1. VM Stacks(虚拟机栈): 每个线程都有一个私有的栈
   * 栈帧: 每个方法都有个栈帧,里面存放了局部变量表,操作数栈,方法出口等信息


2. Native Method Stack(本地方法栈): 与虚拟机栈类似,区别是虚拟机栈执行java方法,本地方法栈执行native方法
3. PC Register(PC寄存器/程序计数器): 每个线程都有一个PC寄存器,指示当前线程执行到哪里了
   如果当前线程执行的是java方法,则寄存器中保存当前指令地址;
   如果当前线程执行的是native方法,则寄存器中保存的值为空.


4. Heap(堆): 所有线程共享,所有对象和数组都在堆上分配,堆可以通过GC进行回收.
5. Method Area(方法区/非堆): 所有线程共享,主要存储类的信息,常量池,变量池,静态变量,方法代码等.

Heap(堆)内存池模型为:


* Young Generation(新生代/年轻代)
   * Eden Space(伊甸园区): 新对象会放到这个区,GC后未回收的进入Survivor Space(幸存者区)
   * Survivor Space(幸存者区)
       * From Survivor
       * To Survivor: 大小与From Survivor相同



* Old Generation(老生代/老年代)


PermGen(永久代)与Metaspace(元空间)

PermGen(永久代)是HotSpot对JVM规范中的Method Area(方法区)的具体实现.

对于动态生成类的情况比较容易出现永久代的溢出,如jsp页面比较多时.

java8中移除了PermGen(永久代),使用Metaspace(元空间)代替.
最大区别在于: 元空间使用本地内存,而不在虚拟机中.
默认情况下,Metaspace(元空间)的上限没有限制,只受制于本地内存大小.

使用Metaspace(元空间)的优点:






讯享网

1. 字符串存在永久代中,容易出现性能问题和内存溢出.
2. 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出.
3. 永久代会为GC带来不必要的复杂度,并且回收效率偏低.




以下只介绍一些常用的参数


堆参数

* -Xms/-Xmx: 初始堆大小(默认为物理内存的1/64)/最大堆大小(默认为物理内存的1/4)
* -Xss: 每个线程堆栈大小.jdk5以后线程堆栈大小为1M,如果栈不是很深,一般128k够用了,大的应用建议256k(这个选项对性能影响比较大,需要严格测试)
* -XX:MinHeapFreeRatio/-XX:MaxHeapFreeRatio: 堆空间的最小空闲比例(默认40),空闲的小于这个值就会进行扩展/最大空闲比例(默认70),空闲的超过这个值时就释放掉部分
   在xmx与xms大小相同时,此配置将无效果.


* -XX:SurvivorRatio: 伊甸园与(一个)幸存者大小的比值(而幸存者有两个: From与To,并且永远一样大)

   比如5,表示伊甸园与From幸存者比例为5:1,与To幸存者比例也是5:1,即伊甸园占总的比例为5/(5+1+1)=57

   如果比例太小,即伊甸园太小,那么新生代GC次数将增加;如果比例太大,那么大部分幸存对象会过早转移到老生代.

* -XX:PretenureSizeThreshold: 大对象直接进入老生代的阀值,单位Byte


年龄

* -XX:TargetSurvivorRatio: 幸存者区目标使用率,默认50(大致表示达到50%使用率时对象会向老生代压缩)
* -XX:MaxTenuringThreshold: 晋升年龄阀值,默认15(即对象在15次Minor GC后会进入老生代)

新生代/老生代大小


关于新生代/老生代大小设置,按优先级顺序(从高到低)有以下几种参数:

1. -XX:NewSize 初始新生代大小/-XX:MaxNewSize 最大新生代大小
2. -Xmn: 新生代大小(相当于初始值与最大值相同)
3. -XX:NewRatio: 老生代与新生代的比例(如4表示老生代:新生代=4:1=4,即新生代占整个堆的1/5)
此值对系统性能影响较大,官方推荐新生代为堆大小的3/8(即老生代占5/8)

元空间





(一般不需要设置)

* -XX:MetaspaceSize: 初始空间
* -XX:MaxMetaspaceSize: 最大空间
* -XX:MinMetaspaceFreeRatio: GC后,最小的空闲空间百分比,如40,如果空闲空间小于这个值,就会增加内存(值设太小可能会影响后面类加载效率,设太大会浪费内存)
* -XX:MaxMetaspaceFreeRatio: GC后,最大的空间空间百分比,如70,如果空闲空间大于这个值,就会释放部分



-XX:+PrintGC/-XX:+PrintGCDetails: 输出GC日志/详细日志
-XX:+PrintGCTimeStamps: 输出GC的时间戳(单位秒,从JVM启动开始计算)
* -XX:+PrintGCDateStamps: 输出GC的时间点(日期的格式)
* -XX:+PrintHeapAtGC: 在GC前后打印堆信息
* -Xloggc:<文件名>: GC日志文件输出路径





* -XX:+UseSerialGC: 使用 Serial(新生代) + SerialOld(老生代)
* -XX:+UseParNewGC: 使用 ParallelNew(新生代) + SerialOld(老生代)
* -XX:+UseParallelGC: 使用 ParallelScavenge(新生代) + SerialOld(老生代)
   * -XX:+UseParallelOldGC: 如果这个参数一起开启,则会使用 ParallelScavenge(新生代) + ParallelOld(老生代),这样老生代效率也更好
   * -XX:+UseAdaptiveSizePolicy: 开启自适应调节策略,这个参数打开后,新生代大小,伊甸园与幸存者区比例,晋升年龄阀值等就不需要手动指定了(默认开启)
* XX:+UseConcMarkSweepGC: 使用 ParallelNew(新生代) + CMS(老生代) + SerialOld(老生代备用,CMS失败时启用)




而在生产环境上,一般使用的是以下几种组合:

* -XX:+UseSerialGC
* -XX:+UseParallelGC -XX:+UseParallelOldGC
* -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
* -XX:+UseG1GC



小讯
上一篇 2025-05-23 08:21
下一篇 2025-06-11 17:07

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/169159.html