概述
堆是线程共享的。用于存放对象实例,几乎所有的对象实例都在这里分配内存。堆也是Java内存管理的核心区域,所以有时候也称之为 ”GC堆“。
设置堆内存大小
堆内存的大小是可以调节的,通过-Xms、-Xmx参数来设置
-Xms20m -Xmx20m (表示最小内存20兆,最大内存20兆)
通常会将-Xms和-Xmx两个参数配置相同的值,其目的是为了能够在Java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小,从而提高性能。
默认情况下
初始内存大小:物理电脑内存大小/64
最大内存大小:物理电脑内存大小/4
如何查看堆内存的内存分配情况
jps -> jstat -gc 进程id
// 或者在程序运行时,通过配置运行参数 -XX:+PrintGCDetails 堆内存细分Java7及之前堆内存逻辑上分为三部分:新生区(Young/New)+养老区(Old/Tenure)+永久区(Permanent Space)
Java8及之后堆内存逻辑上分为三部分:新生区(Young/New)+养老区(Old/Tenure)+元空间(Meta Space)
新生区又被划分为Eden区和Survivor区(From 和 To)
Eden:From:To -> 6 : 1 : 1
新生区:老年区 - > 1 : 2
可通过参数配置各区在堆结构中的占比:
默认-XX:NewRatio=2,表示新生代占1,老年代占2,新生代占整个堆的1/3
可以修改-XX:NewRatio=4,表示新生代占1,老年代占4,新生代占整个堆的1/5
-xx:SurvivorRatio=8,表示Eden空间和另外两个survivor空间所占的比例是8:1:1
当发现在整个项目中,生命周期长的对象偏多,那么就可以通过调整 老年代的大小,来进行调优
几乎所有的Java对象都是在Eden区被new出来的。
绝大部分的Java对象的销毁都在新生代进行了。(有些大的对象在Eden区无法存储时候,将直接进入老年代)
IBM公司的专门研究表明,新生代中80%的对象都是“朝生夕死”的。
可以使用选项"-Xmn"设置新生代最大内存大小(一般不使用)
可以设置参数:-Xx:MaxTenuringThreshold= N 进行设置新生代进入老年代的年龄
堆空间相关的参数设置-XX:+PrintFlagsInitial:查看所有的参数的默认初始值
-XX:+PrintFlagsFinal:查看所有的参数的最终值(可能会存在修改,不再是初始值)
-Xms:初始堆空间内存(默认为物理内存的1/46)
-Xmx:最大堆空间内存(默认为物理内存的1/4)
-Xmn:设置新生代的大小(初始值及最大值)
-XX:NewRatio:配置新生代与老年代在对结构的占比
-XX:SurvivorRatio:设置新生代中Eden和S0和S1空间的占比
-XX:MaxTenuringThreshold:设置新生代垃圾的最大年龄
-XX: +PrintGCDetails:输出详细的GC处理日志
打印gc简要信息:①-Xx: +PrintGC ② -verbose:gc
-XX:HandlePromotionFailure:是否设置空间分配担保
图解YGC过程我们创建的对象,一般都是存放在Eden区,当Eden区满了之后,就会触发GC操作,这个操作一般会称为YGC/Minor GC.
我们继续不断的进行对象生成 和 垃圾回收,当Survivor中的对象的年龄达到15的时候,将会触发一次 Promotion晋升的操作,也就是将年轻代中的对象 晋升到 老年代中
对象分配-图解