堆
1. 堆的细分内存结构:堆空间逻辑上可以分为:新生代,老年代,方法区
- 新生代:又被分为 Eden 区和 Survivor 区
- 老年代:
- 方法区:1.7 及以前叫永久代,1.8及之后叫元空间
2. 堆空间大小的设置和查看:
- -Xms:设置堆空间初始大小,默认初始大小 = 物理内存 / 64,如:-Xms256m
- -Xmx:设置堆空间最大大小,默认最大大小 = 物理内存 / 4,如:-Xmx1024g
- -Xmn:设置新生代最大内存大小
- -XX:NewRatio=N:配置新生代与老年代在堆空间的占比为 1:N,默认为2,表示新生代占1,老年代占2
- -XX:SruvivorRatio=N:设置 Eden 区和 Survivor 比例为 N:1:1, 默认为8,表示 Eden:S1:S2=8:1:1
- -XX:+/-UseAdaptiveSizePolicy:使用/关闭自适应内存分配策略,使用后如果未显示指定 -XX:SruvivorRatio 值,Eden:S1:S2 不一定等于 8:1:1
- -XX:MaxTenuringThreshold=N:设置进入从新生代进入老年代的 age 阈值,默认15
- -XX:UseTLAB:开启 TLAB 空间
- -XX:TLABWasteTargetPercent=N,设置TLAB 空间所占用 Eden 空间的百分比大小,默认 1,表示仅占 Eden 空间 1%
3. MinorGC、MajorGC 与 FullGC 对比:
- MinorGC:新生代的GC,当新生代空间不足时,就会触发 MinorGC,这里的新生代满指的是 Eden 代满,Survivor满不会触发GC,MinorGC会触发 STW
- MajorGC:老年代的GC,目前只有 CMS 支持单独收集老年代的行为,出现 MajorGC,经常会伴随至少一次 MinorGC,MajorGC 速度一般会比 MinorGC 慢10倍以上,STW 时间更长
- FullGC:整个java 堆和方法区的 GC,触发 FullGC 情况一般有如下几种:
- 调用 System.gc(),系统建议执行 FullGC,但不是必然执行
- 老年代空间不足
- 方法区空间不足
- 通过 MinorGC 后进入老年代的平均大小大于老年代的可用内存
- 直接进入老年代的大对象大于老年代可用内存
4. java 内存优化策略:栈内分配、同步消除(锁消除)、标量替换