本文共 1140 字,大约阅读时间需要 3 分钟。
java有内置的垃圾回收器做内存回收,通过强引用、软引用、弱引用和虚引用给对象做"标记",告诉垃圾回收器在什么时机回收什么内存。我先通过JVM options参数探测JVM内部不同垃圾回收的策略。
-Xms10m -Xmx20m -Xmn5m -XX:ReservedCodeCacheSize=240m -XX:+UseCompressedOops -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:./gclogs
// ONE_MB_SIZE = 1024 * 1024byte[] allocate1 = new byte[ONE_MB_SIZE];创建allocate1数组在eden区分配了4096KB*0.25=1MB内存。
byte[] allocate1 = new byte[3 * ONE_MB_SIZE];
JVM将3MB的对象放到了老年代:
为什么JVM不GC然后在新生代上分配3MB空间?这和内存分配与回收策略有关:* 对象优先在eden区分配* 大对象直接进入老年代* 长时间还活着的对象进入老年代
即:
初始我们给heap分配了最大20MB的内存空间,下面看下GC的场景。
此时发生了GC和Full GC:刨除初始被占用的36%的eden区,20MB的heap大小不满足内存分配要求,触发了java.lang.OutOfMemoryError: Java heap space错误。此时将allocate1=null,触发GC,heap刚好可以完成内存分配。此时是在释放了eden空间后,转移到老年代进行内存分配:
To be continued...
转载地址:http://yawza.baihongyu.com/