要做JVM内存垃圾回收首先要明确两个问题:

  1. 哪些内存需要回收
  2. 怎么回收
  3. 什么时候回收

1.哪些内存需要回收

jvm内存可以分为两类:

  1. 线程独占内存区域(程序计数器、虚拟机栈、本地方法栈)
  2. 线程共享区域(堆、方法区)

对于线程独占内存区域来说,他们的回收时机是非常确定的,在方法结束或线程结束的时候回收即可。

对于线程共享区域里的堆和方法区两个区域,都可以进行垃圾收集,但是方法区的收集效率远低于堆,因此java虚拟机规范中不要求虚拟机必须实现方法区的垃圾收集。我们下文中所指的垃圾收集如无特殊说明,都是针对线程共享区域里的堆进行垃圾收集。

既然垃圾收集主要是针对堆进行的,而堆的作用就是存储对象。我们知道,虽然对象存储在堆里,但是如果要真正的使用对象,要通过对象的引用,因此,当一个对象没有引用指向它的时候,我们就可以回收它了。

1.1引用计数算法

给对象添加一个引用计数器,每次被引用就+1,每次有引用失效时,就-1。当对象的引用数量为0时代表对象不可再被使用。

问题:当有对象互相引用的时候,如果这两个互相引用的对象本身都已经不可能再被访问了,但是因为相互引用的关系,他们的引用计数都不是0,也无法被回收。

public class Ref {
public Object instance; public static void main(String[] args) {
Ref a = new Ref();
Ref b = new Ref(); a.instance = b;
b.instance = a; a = null;
b = null; System.gc();// 此时垃圾回收无法回收a、b
}
}

1.2可达性分析算法

目前的主流实现。

基本思想是通过一系列称为"GC Roots"的对象作为起始点向下搜索,搜索走过的路径称为引用链,没有引用链到达的对象视为不可再被使用。

可视为“GC Roots”的对象包括:

  1. 虚拟机栈中的引用对象
  2. 本地方法栈中的引用对象
  3. 方法区中静态属性引用对象、常量引用对象

2.如何回收

垃圾收集算法有以下这些:

标记-清除算法

算法分为“标记”和“清除”两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收。因为被“清除”的对象的内存空间是不连续的,因此清除后会产生大量不连续的内存碎片,内存碎片过多会导致需要分配大对象时找不到连续内存从而触发另一次垃圾回收。

复制算法

将内存划分为容量相等的两块,每次只使用一块,当进行垃圾回收的时候,只将存活的对象复制到另一块内存上,然后将之前的一块内存直接清除。缺点是浪费内存。

现代的商业虚拟机都是使用复制算法来回收新生代的,因为新生代中的对象98%都是朝生夕死,因此不需要按照1:1来划分内存空间,而是将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor中还活着的对象一次性复制到另一块Survivor上,最后清理掉Eden和刚才用过的Survivor空间。

标记-整理算法

和标记-清除算法类似,标记阶段是一样的,只是后续不直接清除可回收对象,而是让所有存活的对象向一端移动,然后清除掉端边界以外的内存。

分代收集算法

这个算法并没有什么新的思想,只是根据对象存活周期将内存划分为几块,每块根据存活周期选择最合适的算法。一般是分为新生代和老年代。新生代每次垃圾收集都只有少量对象存活,可以选择复制算法;老年代因为对象存活率高,没有额外空间对它进行分配担保,因此可以选择“标记-清理”或“标记-整理”算法。

3.什么时候回收

GC有三种:

  1. Minor GC:对年轻代(包括Eden和Survivor区域)回收内存叫做Minor GC。
  2. Major GC:对老年代回收内存称为Major GC。Major GC速度一般比Minor GC慢10倍以上。
  3. Full GC:对整个堆进行内存回收,在最近几个版本的JDK里默认包括了对永久代即方法区的回收(JDK8中无永久代了)。

Minor GC触发时机:

当Eden区满时,触发Minor GC。

Full GC触发时机:

  1. 调用System.gc()时,系统建议执行Full GC,但是不必然执行。
  2. 老年代空间不足
  3. 永久代(方法区)空间不足
  4. 通过Minor GC后进入老年代的平均大小大于老年代的可用内存
  5. 当Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

JVM垃圾收集器基本思想的更多相关文章

  1. JVM调优:HotSpot JVM垃圾收集器

    HotSpot JVM垃圾收集器 - Snooper - 博客园https://www.cnblogs.com/snooper/p/8718478.html

  2. JVM垃圾收集器-Parallel Scavenge收集器

    今天我给大家讲讲JVM垃圾收集器-Parallel Scavenge收集器 Parallel Scavenge收集器 Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的 ...

  3. 7种JVM垃圾收集器特点,优劣势、及使用场景

    今天继续JVM的垃圾回收器详解,如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集器就是内存回收的具体实现. 一.常见的垃圾收集器有3类 1.新生代的收集器包括 Serial PraNew Pa ...

  4. 【006】【JVM——垃圾收集器总结】

     Java虚拟机学习总结文件夹 JVM--垃圾收集器总结 垃圾收集器概览 收集算法是内存回收的方法论.垃圾收集据是内存回收的详细实现.Java虚拟机规范中对垃圾收集器应该怎样实现没有规定.不同的厂 ...

  5. 第五章 JVM垃圾收集器(1)

    说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法> 1.七种垃圾收集器 Serial(串行GC)-- 复制 ParNew(并行GC)-- ...

  6. 第六章 JVM垃圾收集器(2)

    上一章记录了几种常见的垃圾收集器,见<第五章 JVM垃圾收集器(1)> 1.G1 说明: 从上图来看,G1与CMS相比,仅在最后的"筛选回收"部分不同(CMS是并发清除 ...

  7. JVM垃圾收集器(1)

    此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法& ...

  8. 5种JVM垃圾收集器特点和8种JVM内存溢出原因

    先来看看5种JVM垃圾收集器特点 一.常见垃圾收集器 现在常见的垃圾收集器有如下几种: 新生代收集器: Serial ParNew Parallel Scavenge 老年代收集器: Serial O ...

  9. 7种 JVM 垃圾收集器特点、优劣势及使用场景(多图)

    7种 JVM 垃圾收集器特点.优劣势及使用场景(多图)  mp.weixin.qq.com 点击上方"IT牧场",选择"设为星标"技术干货每日送达! 一.常见垃 ...

随机推荐

  1. [转]Linux软连接和硬链接

    1.Linux链接概念 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接. [硬连接]硬连接指通过索引节 ...

  2. shell中判读文件存在的方法

    单个文件较简单 if [[ -f filename ]]; then echo exist fi 文件存在并且有内容 if [[ -s filename ]]; then echo exist fi ...

  3. ZAM 3D 制作3D动画字幕 用于Xaml导出

    原地址-> http://www.cnblogs.com/yk250/p/5662788.html 介绍:对经常使用Blend做动画的人来说,ZAM 3D 也很好上手,专业制作3D素材的XAML ...

  4. 思考方式--SMART原则

    如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 万事开头于你目标的设定,如果开始走错了,那么后面的路将会更加的错误,甚至于更加的努力 ...

  5. python 面试必读

    总结了10道题的考试侧重点,供参考: 1.How are arguments passed – by reference of by value? 考的是语法,基本功,虽说python程序员可以不用关 ...

  6. winFrom 常用控件属性及方法介绍

    目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox(文本框)控件 4.RichTextBox控件 5.NumericUpDown控件 6.Button(按钮)控件 7.Gro ...

  7. css3动画3

    1.transition过渡动画 2.@keyframes关键帧动画,配合transform.animation使用

  8. 使用英文版eclipse保存代码,出现some characters cannot be mapped using "Cp1251" character encoding.

    some characters cannot be mapped using "Cp1251" character encoding. 解决办法:方案一: eclipse-> ...

  9. 我在使用vs进行C#编程中常用的几个快捷键

    在vs中进行C#编程时: (1)输入svm然后按Tab键会生成Main函数: (2)Ctrl +k+s 三个键一起按,会调出代码段:选中多行后,然后按以上三个快捷键,输入需要使用的代码段,按下Tab, ...

  10. matlab 去掉字符串前后的空格

    strtrim 从字符串,删除开头和结尾的空白 句法 S = strtrim(STR) C = strtrim(CSTR)