一、如何确定某个对象是垃圾?

public class Main {public static void main(String[] args) {MyObject object1 = new MyObject();MyObject object2 = new MyObject();object1.object = object2;object2.object = object1;object1 = null;object2 = null;}
}class MyObject{public Object object = null;
}

代码所示:

最后面两句将object1和object2赋值为null,也就是说object1和object2指向的对象已经不可能再被访问,但是由于它们互相引用对方,导致它们的引用计数都不为0,那么垃圾收集器就永远不会回收它们。为了解决这个问题我们提出可达性分析法。

可达性分析法:


通过一系列的 ‘GC Roots’ 的对象作为起始点,从这些节点出发所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连的时候说明对象不可用。


可作为 GC Roots 的对象:

1、虚拟机栈(栈帧中的本地变量表)中引用的对象

2、方法区中类静态属性引用的对象

3、方法区中常量引用的对象

4、本地方法栈中 JNI(即一般说的 Native 方法) 引用的对象

java对象的引用:
强引用:

类似于 Object obj = new Object(); 创建的,只要强引用在就不回收。

软引用:

SoftReference 类实现软引用。在系统要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行二次回收。

弱引用:

WeakReference 类实现弱引用。对象只能生存到下一次垃圾收集之前。在垃圾收集器工作时,无论内存是否足够都会回收掉只被弱引用关联的对象。

虚引用:

PhantomReference 类实现虚引用。无法通过虚引用获取一个对象的实例,为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

二、典型的垃圾收集算法

1.Mark-Sweep(标记-清除)算法

这是最基础的垃圾回收算法,之所以说它是最基础的是因为它最容易实现,思想也是最简单的。标记-清除算法分为两个阶段:标记阶段和清除阶段。标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占用的空间。具体过程

2.Copying(复制)算法

把空间分成两块,每次只对其中一块进行 GC。当这块内存使用完时,就将还存活的对象复制到另一块上面。

举例子:

解决前一种方法的不足,但是会造成空间利用率低下。因为大多数新生代对象都不会熬过第一次 GC。所以没必要 1 : 1 划分空间。可以分一块较大的 Eden 空间和两块较小的 Survivor 空间,每次使用 Eden 空间和其中一块 Survivor。当回收时,将 Eden 和 Survivor 中还存活的对象一次性复制到另一块 Survivor 上,最后清理 Eden 和 Survivor 空间。大小比例一般是 8 : 1 : 1,每次浪费 10% 的 Survivor 空间。但是这里有一个问题就是如果存活的大于 10% 怎么办?这里采用一种分配担保策略:多出来的对象直接进入老年代。

3.Mark-Compact(标记-整理)算法

不同于针对新生代的复制算法,针对老年代的特点,创建该算法。主要是把存活对象移到内存的一端。

4.Generational Collection(分代收集)算法

根据存活对象划分几块内存区,一般是分为新生代和老年代。然后根据各个年代的特点制定相应的回收算法。

新生代:

每次垃圾回收都有大量对象死去,只有少量存活,选用复制算法比较合理。

老年代:

老年代中对象存活率较高、没有额外的空间分配对它进行担保。所以必须使用 标记 —— 清除 或者 标记 —— 整理 算法回收。

三.典型的垃圾收集器

HotSpot(JDK 7)虚拟机提供的几种垃圾收集器,用户可以根据自己的需求组合出各个年代使用的收集器。

1.Serial/Serial Old

Serial/Serial Old收集器是最基本最古老的收集器,它是一个单线程收集器,并且在它进行垃圾收集时,必须暂停所有用户线程。Serial收集器是针对新生代的收集器,采用的是Copying算法,Serial Old收集器是针对老年代的收集器,采用的是Mark-Compact算法。它的优点是实现简单高效,但是缺点是会给用户带来停顿。

2.ParNew

ParNew收集器是Serial收集器的多线程版本,使用多个线程进行垃圾收集。

3.Parallel Scavenge

Parallel Scavenge收集器是一个新生代的多线程收集器(并行收集器),它在回收期间不需要暂停其他用户线程,其采用的是Copying算法,该收集器与前两个收集器有所不同,它主要是为了达到一个可控的吞吐量。

4.Parallel Old

Parallel Old是Parallel Scavenge收集器的老年代版本(并行收集器),使用多线程和Mark-Compact算法。

5.CMS

CMS(Current Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,它是一种并发收集器,采用的是Mark-Sweep算法。

6.G1

G1收集器是当今收集器技术发展最前沿的成果,它是一款面向服务端应用的收集器,它能充分利用多CPU、多核环境。因此它是一款并行与并发收集器,并且它能建立可预测的停顿时间模型。

GC内存分配与回收策略:

1、大对象直接进入老年代

2、长期存活的对象将进入老年代

3、动态对象年龄判定

4、 空间分配担保

对象的内存分配,往大方向上讲就是在堆上分配,对象主要分配在新生代的Eden Space和From Space,少数情况下会直接分配在老年代。如果新生代的Eden Space和From Space的空间不足,则会发起一次GC,如果进行了GC之后,Eden Space和From Space能够容纳该对象就放在Eden Space和From Space。在GC的过程中,会将Eden Space和From  Space中的存活对象移动到To Space,然后将Eden Space和From Space进行清理。如果在清理的过程中,To Space无法足够来存储某个对象,就会将该对象移动到老年代中。在进行了GC之后,使用的便是Eden space和To Space了,下次GC时会将存活对象复制到From Space,如此反复循环。当对象在Survivor区躲过一次GC的话,其对象年龄便会加1,默认情况下,如果对象年龄达到15岁,就会移动到老年代中。

一般来说,大对象会被直接分配到老年代,所谓的大对象是指需要大量连续存储空间的对象,最常见的一种大对象就是大数组,比如:

byte[] data = new byte[4*1024*1024]

这种一般会直接在老年代分配存储空间。

当然分配的规则并不是百分之百固定的,这要取决于当前使用的是哪种垃圾收集器组合和JVM的相关参数。

java垃圾回收GC(学习笔记)相关推荐

  1. java垃圾回收机制_笔记 | Java垃圾回收机制

    本文经授权转载自程序员杂货铺(ID:speakFramework) 垃圾回收 最近上海的小伙伴是不是要被强垃圾分类搞疯了???哈哈哈哈 上海是个走在前列的城市啊,不光骑自行车闯红灯要被罚钱,垃圾不分类 ...

  2. java 垃圾回收GC(CMS、G1)原理及调优

    概述 本文介绍GC基础原理和理论,GC调优方法思路和方法,基于Hotspot jdk1.8,学习之后将了解如何对生产系统出现的GC问题进行排查解决 阅读时长约30分钟,内容主要如下: GC基础原理,涉 ...

  3. [JVM-3]Java垃圾回收(GC)机制和垃圾收集器选择

    哪些内存需要回收? 1.引用计数法 这个算法的实现是,给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1:当引用失效时,计数器值-1.任何时刻计数值为0的对象就是不可能再被使用的.这 ...

  4. Java垃圾回收GC概览

    自动内存管理     这部分的内容可以说是重中之重了,有过C/C++开发工作的人应该知道内存管理的重要性和难度.虽然Java自己实现了内存管理,不用开发人员去操心,但其内存管理还是有不足之处,常常也会 ...

  5. Java 垃圾回收(GC)

    目录 前言 什么是垃圾 可达性分析 GC Root 对象 什么时候回收 如何回收垃圾 标记清除算法(Mark and Sweep GC) 复制算法(Copying) 标记-压缩算法 (Mark-Com ...

  6. 细述 Java垃圾回收机制→How Java Garbage Collection Works?

    本文非原创,翻译自How Java Garbage Collection Works? 在Java中为对象分配和释放内存空间都是由垃圾回收线程自动执行完成的.和C语言不一样的是Java程序员不需要手动 ...

  7. Java 垃圾回收机 GC Roots详解(Garbage Collection Roots)

    背景: 之前面试阿里支付宝,被问到常见的GC Root 是什么? 当时自己支支吾吾,明明自己看过深入理解Java 虚拟机这本书,但是就是回答不上来. 后来自己工作中,遇到内存泄漏问题.我百度,下载了M ...

  8. 53.垃圾回收算法的实现原理、启动Java垃圾回收、Java垃圾回收过程、垃圾回收中实例的终结、对象什么时候符合垃圾回收的条件、GC Scope 示例程序、GC OutOfMemoryError的示例

    53.垃圾回收算法的实现原理 53.1.目录 53.2.启动Java垃圾回收 53.3.Java垃圾回收过程 53.4.垃圾回收中实例的终结 53.5.对象什么时候符合垃圾回收的条件? 53.5.1. ...

  9. [译]GC专家系列2:Java 垃圾回收的监控

    原文链接:http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/ 这是GC专家系列文章的第二篇. ...

最新文章

  1. python实用脚本-python 实用脚本
  2. 【jQuery】使用Ajax提单表单数据
  3. const constexpr C++ 解释
  4. php private方法,php如何调用private方法
  5. 前端学习(2042)vue之电商管理系统电商系统之优化生成打包报告
  6. 文件名为空linux,文件系统:隐匿在Linux背后的机制
  7. matlab连接mysql数据库_matlab连接数据库的问题
  8. 智慧城市java开发_智慧城市主界面开发 使用eclipse开发智慧城市APP源码 - 下载 - 搜珍网...
  9. Atitit 技术趋势的管理之道 attilax著 1. 技术趋势 即是新特性 3 1.1. 几个大趋势 3 1.2. 可读性大于性能趋势 3 2. 趋势来源渠道 4 2.1. 技术趋势Thought
  10. javascript 下载和打印文件流
  11. EditText属性及一些常用用法
  12. 无法打开coursera网站解决方案
  13. ImageAssitant插件 — 一件提取网页图片
  14. hadoop-uber作业模式
  15. 深圳移动 神州行(大众卡/轻松卡/幸福卡)套餐资费(含香港日套餐)信息及使用方法
  16. 学习可爱彩色线条PS极简马克笔简笔画:饮品篇
  17. EverEdit 4.2.0.4457 免安装已激活 x64
  18. C++(30)—奇偶数判断
  19. Oracle SQL性能优化 SQL优化
  20. FPGA知识查漏补缺——为什么setup summary和hold suammay的data path延时不一致

热门文章

  1. PAT1105:Spiral Matrix
  2. ACM学习历程—HDU 2112 HDU Today(map spfa 优先队列)
  3. sqlserver 中的GUID 全局唯一标识 -摘自网络
  4. js-sdk探索之微信网页分享
  5. java中的List排序[转]
  6. access 如何使用dolby_用Access开发《生产管理系统》
  7. c++ map底层_Redis详解(四)------ redis的底层数据结构
  8. linux noprobe参数,find 命令的参数详解
  9. c保留小数点后三位数没有则为0_C语言中……“计算结果保留三位小数。”怎么表示?...
  10. 平面设计背景素材|打造超酷的炫彩光束光效海报!