当先锋百科网

首页 1 2 3 4 5 6 7

内存分配与回收策略:Java 技术体系的自动内存管理最根本的目标是自动化地解决两个问题:自动给对象分配内存以及自动回收分配给对象的内容

  1. 大多数情况下,对象在新生代 Eden 区分配,当 Eden 没有足够空间进行分配时,VM 会发起一次 Minor GC。而 GC 期间如果发现存活的对象无法放入 Survivor 中就会通过分配担保机制提前移到老年代区。而后将年轻代重新分配对象。
  2. 如果Java 堆可供分配大小为 20M(-Xms20M(初始堆)、-Xmx20M(最大堆)、-Xmn10M(新生代)),这三个参数限制了 Java 堆大小为20M,不扩展,其中 10M 分配给新生代,剩下 10M分配给老年代(默认是1:2),( -XX:SurvivorRatio=8 决定了新生代中 Eden 与 Survivor 空间比为 8:1。
  3. 大对象直接进入老年代:(-XX:PretenureSizeThreshold=1024 超过1024就直接在老年代分配)避免对象在 Eden 和 Survivor 间来回复制,产生大量内存复制操作。
  4. 长期存活的对象将进入老年代:如何判定哪些对象进入老年代?VM 给每个对象定义了一个对象年龄(Age)计数器,存储在对象头中。对象通常在 Eden 中诞生,如果经过一次 Minor GC 后仍存活且能被 Survivor 容纳的话,该对象就移到 Survivor 中且 Age + 1,当它的 Age 加到一定程度(默认是15)就会晋升到老年代中。可通过 -XX:MaxTenuringThreshold 设置。
  5. 为了能更好地适应内存状况,HotSpot VM 并不是永远要求对象的年龄达到设定的值,如果 Survivor 中相同年龄所有对象大小总和大于 Survivor 空间的一般,年龄大于或等于该年龄的对象就可以直接进入老年代。
  6. 空间分配担保:在发生 Minor GC 之前,VM 必须先检查老年代最大可用连续空间是否大于新生代所有对象总空间
    1. 如果条件成立,那就 Minor GC,
    2. 如果不成立,VM 会先查看 -XX:HandlePromotionFailure 设置的值是否允许担保失败,
    1. 如果允许,继续检查老年代最大可用空间是否大于历次晋升到老年代的平均大小
    1. 如果大于,将尝试 Minor GC,
    2. 如果小于或 -XX 设置不允许冒险,将会进行一次 Full GC。