JVM内存分配和回收策略总结(以Hotspot为例)

一、内存区域分类

JVM区域总体分两类,heap区和非heap区。
Heap区又分为:

  1. Eden Space(伊甸园)、
  2. Survivor Space(幸存者区)、
  3. Old Gen(老年代)。

非heap区又分:

  1. Code Cache(代码缓存区);
  2. Perm Gen(永久代);
  3. JVM Stack(java虚拟机栈);
  4. Local Method Statck(本地方法栈);

二、分配策略

  1. 对象优先在Eden分配,内存不足时发起Minor GC。
  2. 大对象直接进入老年代
    1. 典型:很长的字符串和数组。
    2. 原因:避免大量复制。(新生代基于复制算法)
  3. 长期存活的对象直接进入老年代
    1. 通过Age计算器,每次Minor GC+1,默认15岁。
  4. 动态对象年龄判定
    1. 如果Survivor中相同年龄的对象大于空间的一半,把大于该年龄的放入老年代。
  5. 空间分配担保
    1. 在MinorGC后,内存还不足时让老年代担保,再不行则进行Full GC。

三、回收策略

1、When

对象不可达时回收。

引用计数法

可达性分析算法

  1. 基于GC Roots对象为根节点。
  2. 经过两次标记不可达。
  3. Hotspot通过OopMap的数据结构直接指向对象引用。

多种引用

目的:利用缓存,有空间保留,无空间抛弃。

  1. 强引用:无论如何保留
  2. 软引用:有空间保留,内存要溢出时清理,通过SoftReference
  3. 弱引用:保留到下次收集前,WeakReference
  4. 虚引用:待回收给GC一个通知,PhantomReference

2、How

标记-清除:效率不高,存在内存碎片。
复制:效率高,但需要额外内存,一般用于新生代。
标记-整理:内存利用率高,效率不高,一般用于老年代。
分代法&分区法:G1收集器采用分代和内存分区回收机制,避免全区域收集。
并发收集

Comments
Write a Comment