[关闭]
@ZeroGeek 2015-09-25T01:35:35.000000Z 字数 2270 阅读 696

GC基本原理学习(Garbage Collected)

Java 基础知识 每周主题


引言

Java的内存动态分配和垃圾收集的问题,都交给了JVM来处理。意注,将JVM运行数据区(虚拟机栈【栈帧】,程序计数器,堆内存)粗略的分为栈和堆(所有线程共享),回收的是堆中的对象实例。不是栈中的引用类型。
绘制的内存图
那么JVM是如何处理的?
从三个问题来分析:
1. 哪些内存需要回收?
2. 什么时候进行回收?
3. 如何回收?

注:现代收集器基本采用分代收集算法,堆分为:新生代和老年代。

1. 哪些内存需要回收?什么时候回收?

1.1 了解下对象的创建:

  1. 通过new 关键字。
  2. JVM遇到new指令,检查是否能在常量池中定位到一个类的符号引用。
  3. 检查是否已被加载,解析,初始化过。
  4. 没有,则执行相应的类加载过程。
  5. 类加载检查通过后,为新生对象分配内存。(类加载后确定对象所需内存大小)
  6. 从Java堆中划分出一块确定的内存。

1.2 若为“死亡”的对象,则需要回收,如何判断对象是否存活?

1.2.1 引用计数算法

1.2.2 可达性分析算法

1.2.3 哪些可作为GC Roots的对象?

1.2.4 无论哪种算法都是与“引用”有关,下面分析引用的4种类型,强度依次减弱。

1.2.5 详解,真正的"死亡"对象(两次标记后进行回收

事实上,不可达的对象,也并非“非死不可”,这时它们处于“缓刑”阶段,真正死亡至少要经历两次标记过程:

1.2.5.1 第一次标记
1.2.5.2 第二次标记【需要执行finalize(),通过筛选】

1.3 上面讲的是需要回收的堆内存,关于回收方法区(或HotSpot虚拟机中的永久代),效率低

1.3.1 废弃常量

1.3.2 无用的类

2. 如何回收?【垃圾收集算法】

2.1 标记-清除[Mark-Sweep]算法

2.2 复制[Copying]算法

2.3 标记-整理[Mark-Compact]算法

2.4 分代收集[Generational Collection]算法(商业虚拟机主要采用方法)

关于内存泄露

  1. OutOfMemoryError异常,java堆溢出:-Xms ,-Xmx
    对象不断被创建,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。
  2. VM Stack溢出。-Xss
  3. 常量池溢出。-XX:PermSize,-XX:MaxPermSize

参考:《深入理解Java虚拟机》

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注