关于垃圾回收,主要是两个步骤:

  1. 垃圾对象的判断
  2. 垃圾对象的回收

垃圾对象的判断方法

  1. 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象,就是垃圾对象。
  2. 可达性分析算法:通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,当一个对象到GC Roots没有任何路径相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则此对象为垃圾对象。

那么,哪些对象可以被认为是“GC Roots”对象呢,如下

  • Class - 由系统类加载器加载的对象,这些类是不能够被回收的,他们可以以静态字段的方式保存持有其它对象。
  • Thread - 活着的线程
  • Stack Local - Java方法的local变量或参数
  • JNI Local - JNI方法的local变量或参数
  • JNI Global - 全局JNI引用
  • Monitor Used - 用于同步的监控对象
  • Held by JVM - 用于JVM特殊目的由GC保留的对象,但实际上这个与JVM的实现是有关的。可能已知的一些类型是:系统类加载器、一些JVM知道的重要的异常类、一些用于处理异常的预分配对象以及一些自定义的类加载器等。然而,JVM并没有为这些对象提供其它的信息,因此就只有留给分析分员去确定哪些是属于"JVM持有"的了。

垃圾对象的回收方法

先来看下垃圾回收的三种算法

复制算法

将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

“标记-清除”(Mark-Sweep)算法

首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象;

它主要有两个不足:一个是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片;

标记-整理算法

标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

那么,垃圾对象是如何回收的呢?答案是分代回收。

分代回收策略

  不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。分代垃圾回收采用分治的思想,进行代的划分,把不同生命周期的对象放在不同代上,不同代上采用最适合它的垃圾回收方式进行回收。

  一般,Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。

  在新生代中,有大批对象死去,只有少量存活,一般选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。新生代分三个区。一个Eden区,两个Survivor区(救助空间,一般而言)。大部分对象在Eden区中生成,当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个);新创建的对象的内存都分配自eden,Minor collection的过程就是将eden和在survivor space中的活对象copy到空闲survivor space中,对象在新生代里经历了一定次数(可以通过参数配置)的minor collection后,就会被移到老年代中,称为tenuring。

  老年代中因为对象存活率高,不需要大量清理或整理,因此使用“标记—清理”或者“标记—整理”算法来进行回收。

  GC分为两种,Scavenge GC和Full GC;

  • Scavenge GC:对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。
  • Full GC:对整个堆进行GC,包括Young、Tenured和Perm。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。尽可能减少Full GC的次数

  有如下原因可能导致Full GC:

  • 年老代(Tenured)被写满
  • 持久代(Perm)被写满
  • System.gc()被显示调用
  • 上一次GC之后Heap的各域分配策略动态变化

参考:

《深入理解Java虚拟机》

http://blog.csdn.net/fenglibing/article/details/8928927

Java中的垃圾回收的更多相关文章

  1. 【java虚拟机序列】java中的垃圾回收与内存分配策略

    在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...

  2. java中存在垃圾回收机制,但是还会有内存泄漏的问题,原因是

    答案是肯定的,但不能拿这一句回答面试官的问题.分析:JAVA是支持垃圾回收机制的,在这样的一个背景下,内存泄露又被称为“无意识的对象保持”.如果一个对象引用被无意识地保留下来,那么垃圾回收器不仅不会处 ...

  3. Java中的垃圾回收算法详解

    一.前言   前段时间大致看了一下<深入理解Java虚拟机>这本书,对相关的基础知识有了一定的了解,准备写一写JVM的系列博客,这是第二篇.这篇博客就来谈一谈JVM中使用到的垃圾回收算法. ...

  4. Java中的垃圾回收机制

    1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...

  5. java中的垃圾回收机

    任何语言在运行过程中都会创建对象,也就意味着需要在内存中为这些对象在内存中分配空间,在这些对象失去使用的意义的时候,需要释放掉这些内容,保证内存能够提供给新的对象使用.对于对象内存的释放就是垃圾回收机 ...

  6. JAVA中的垃圾回收机制以及其在android开发中的作用

    http://blog.csdn.net/xieqibao/article/details/6707519 这篇文章概述了JAVA中运行时数据的结构,以及垃圾回收机制的作用.在后半部分,描述了如何检测 ...

  7. Java中的垃圾回收机制&内存管理&内存泄漏

    1. Java在创建对象时,会自动分配内存,并当该对象引用不存在的时候,释放这块内存. 为什么呢? 因为Java中使用被称为垃圾收集器的技术来监视Java程序的运行,当对象不再使用时,就自动释放对象所 ...

  8. java中的垃圾回收算法与垃圾回收器

    常用的垃圾回收算法 标记-清除 标记清除算法是一种非移动式的回收算法,分为标记 清除 2个阶段,简而言之就是先标记出需要回收的对象,标记完成后再回收掉所有标记的内存对象,如下图 可见回收后图中被标记的 ...

  9. java虚拟机之垃圾回收算法

    标记-清除算法: 这是最基础的,就是之前所讲的两次标记,首先标记出所有 需要回收的对象,然后进行统一清除, 这有两缺点:一是效率低,标记和清除(开启低优先级进行回收)都是低效率的.第二是空间问题,标记 ...

随机推荐

  1. asp.net判断FileUpload选择的文件是否是图片

    假如keleyi.aspx页面中有一个ID为fuHovertree的FileUpload控件,那么C#代码怎么判断fuHovertree选择的文件是否是图片呢? 代码如下: HttpPostedFil ...

  2. Java连接MYSQL 数据库的连接步骤

    这篇文章主要以MySQL为例讲下Java如何连接到数据库的. 当然,首先要安装有JDK(一般是JDK1.5.X).然后安装MySQL,这些都比较简单,具体过程就不说了.配置好这两个环境后,下载JDBC ...

  3. hibernate---注释 ----(购物:人顾客售货员boss)

    package com.ij34.dao; import javax.persistence.*; @Entity @Inheritance(strategy=InheritanceType.JOIN ...

  4. java servlet手机app访问接口(四)推送

    一. 服务端DEMO下载及运行. 登录友盟后,浏览器直接输入下面这个URL,直接进入文档开发和DEMO下载页面:http://dev.umeng.com/push/ios/integration(下面 ...

  5. Java基础复习笔记系列 八 多线程编程

    Java基础复习笔记系列之 多线程编程 参考地址: http://blog.csdn.net/xuweilinjijis/article/details/8878649 今天的故事,让我们从上面这个图 ...

  6. Scalaz(3)- 基础篇:函数概括化-Generalizing Functions

    Scalaz是个通用的函数式编程组件库.它提供的类型.函数组件都必须具有高度的概括性才能同时支持不同数据类型的操作.可以说,scalaz提供了一整套所有编程人员都需要的具有高度概括性的通用函数,它是通 ...

  7. [moka同学笔记]Yii2 自定义class、自定义全局函数(摘录)

    1.在app\components下新建MyComponent.PHP namespace app\components; use Yii; use yii\base\Component; use y ...

  8. PHP知识库图谱汇总(完善中)

    基本语法不做汇总 经典算法: 冒泡算法.快速算法.二分查找 字符串处理: 字符串查找 字符串排序 字符串切割 字符串定位 字符串对比 字符串大小写转换 Session和Cookies: Session ...

  9. Lucene.net站内搜索—6、站内搜索第二版

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  10. c# datagridview禁止自动生成额外列

    在某些时候,处于重用pojo的考虑,我们希望在不同的datagridview之间进行复用,这就涉及到pojo中的字段会比有些datagridview所需要的字段多,默认情况下,.net对于pojo中的 ...