1. 年轻代图片
- 年轻代(Young)属于JVM堆内存空间的一个组成部分
-
所有使用关键字new新实例化的对象一定会在伊甸园区进行保存,而对于存活区保存的一定是已经在伊甸园区存在一段时间并且经过了几次Minor GC还保存下来的活跃对象。那么这个对象将晋升到 存活区之中。
-
存活区分成两块内存空间,并且空间大小相等,目的是:一块存活区为了晋升、另外一块存活区为了对象回收。这两块内存空间一定有一块是空的。
2. 年轻代GC(Minor GC)实现算法—复制算法(Copying)
-
算法:复制采用的方式为从根集合扫描出存活的对象,并将找到的存活对象复制到一块新的完全未使用的空间中。
-
红色为不存活的对象所占用的内存空间,绿色为存活对象所占用的内存空间。
3. 年轻代优化算法
- 由于Eden区总会保存大量的新生对象或大量临时对象,会频繁执行Minor GC,所以HotSpot虚拟机为了加快此空间的内存分配,使用了以下两种技术:
-
Bump-The-Pointer
- 该技术的主要特点是跟踪在Eden区保存的最后一个对象,这个最后保存的对象一般会保存在Eden区的顶部,这样每次创建新对象时只需要检查最后保存的对象后面是否有足够的空间就可以很快地判断出Eden区中是否还有剩余空间,这种做法可以极大地提高内存分配速度。
-
TLAB(Thread-Local Allocation Buffers)
- 虽然“Bump-The-Pointer”算法可以提高内存的分配速度,但是这种做法并不适合多线程的操作情况。所以又采用了“TLAB”算法将Eden区分为多个数据块,每个数据块分别使用“Bump-The-Pointer”技术进行对象保存于内存分配。
4. 年轻代内存调整参数
No. | 参数名称 | 描述 |
---|---|---|
01 | -Xmn | 设置年轻代堆内存大小,默认为物理内存的 1/64 |
02 | -Xss | 设置每个线程栈大小,JDK1.5之后默认为每个线程分配1M的栈大小,减少此数值可以产生更多的线程对象,但是不能无限生成 |
03 | -XX:SurvivorRatio | 设置Eden与Survivor空间的大小比例,默认 8:1:1,不建议修改 |
04 | -XX:NewSize | 设置新生代内存区大小 |
05 | -XX:NewRatio | 设置年轻代与老年代的比率 |
5. 范例:改变存活区的比率
-
代码
public class TestDemo { public static void main(String[] args) { } }
-
终端运行
> javac TestDemo.java > java -Xmx10M -Xms10M -XX:SurvivorRatio=6 -XX:+PrintGCDetails TestDemo
-
运行结果(存在一定误差)
Heap PSYoungGen total 2560K, used 975K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000) eden space 2048K, 47% used [0x00000000ffd00000,0x00000000ffdf3ca0,0x00000000fff00000) from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000) to space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000) ParOldGen total 7168K, used 0K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000) object space 7168K, 0% used [0x00000000ff600000,0x00000000ff600000,0x00000000ffd00000) Metaspace used 2559K, capacity 4486K, committed 4864K, reserved 1056768K class space used 281K, capacity 386K, committed 512K, reserved 1048576K