Java中的垃圾回收
关于垃圾回收,主要是两个步骤:
- 垃圾对象的判断
- 垃圾对象的回收
垃圾对象的判断方法
- 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象,就是垃圾对象。
- 可达性分析算法:通过一系列的称为“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中的垃圾回收的更多相关文章
- 【java虚拟机序列】java中的垃圾回收与内存分配策略
在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...
- java中存在垃圾回收机制,但是还会有内存泄漏的问题,原因是
答案是肯定的,但不能拿这一句回答面试官的问题.分析:JAVA是支持垃圾回收机制的,在这样的一个背景下,内存泄露又被称为“无意识的对象保持”.如果一个对象引用被无意识地保留下来,那么垃圾回收器不仅不会处 ...
- Java中的垃圾回收算法详解
一.前言 前段时间大致看了一下<深入理解Java虚拟机>这本书,对相关的基础知识有了一定的了解,准备写一写JVM的系列博客,这是第二篇.这篇博客就来谈一谈JVM中使用到的垃圾回收算法. ...
- Java中的垃圾回收机制
1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...
- java中的垃圾回收机
任何语言在运行过程中都会创建对象,也就意味着需要在内存中为这些对象在内存中分配空间,在这些对象失去使用的意义的时候,需要释放掉这些内容,保证内存能够提供给新的对象使用.对于对象内存的释放就是垃圾回收机 ...
- JAVA中的垃圾回收机制以及其在android开发中的作用
http://blog.csdn.net/xieqibao/article/details/6707519 这篇文章概述了JAVA中运行时数据的结构,以及垃圾回收机制的作用.在后半部分,描述了如何检测 ...
- Java中的垃圾回收机制&内存管理&内存泄漏
1. Java在创建对象时,会自动分配内存,并当该对象引用不存在的时候,释放这块内存. 为什么呢? 因为Java中使用被称为垃圾收集器的技术来监视Java程序的运行,当对象不再使用时,就自动释放对象所 ...
- java中的垃圾回收算法与垃圾回收器
常用的垃圾回收算法 标记-清除 标记清除算法是一种非移动式的回收算法,分为标记 清除 2个阶段,简而言之就是先标记出需要回收的对象,标记完成后再回收掉所有标记的内存对象,如下图 可见回收后图中被标记的 ...
- java虚拟机之垃圾回收算法
标记-清除算法: 这是最基础的,就是之前所讲的两次标记,首先标记出所有 需要回收的对象,然后进行统一清除, 这有两缺点:一是效率低,标记和清除(开启低优先级进行回收)都是低效率的.第二是空间问题,标记 ...
随机推荐
- 基于Ionic2的开源项目
项目介绍 基于Ionic2的Ionic中文论坛客户端,该应用也是边学边做的,为了将更多常用东西加入到APP中,有些逻辑不通之处,敬请包涵. 开源地址 https://github.com/zxj963 ...
- Java中Sting转Timestamp
Java中Sting转Timestamp 时间转换.png
- android 6.0添加权限
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissio ...
- 设计模式/原则篇- Unit of Work
概念 Unit of Work 即工作单元. 用来维护一组受业务影响的对象列表,将多个操作放在一个单元中,把操作原子化,通过事务统一完成一次提交,如果某个过程出现异常,就将所有修改进行回滚,保证数据的 ...
- jQuery Countdown Timer 倒计时效果
这个一款简单的 jQuery 倒计时插件,用于显示剩余的天数,小时,分钟和秒.倒计时功能是非常有用的一个小功能,可以告诉用户多久以后您的网站将会发布或者关闭进行维护,还可以用于举办活动的开始和停止的倒 ...
- 系统安装LOL等游戏后出现VS调试报错"无法调试""拒绝访问"之类的调试错误
一个问题抠得脑壳痛,度娘一番各种各样的答案.基本属于 1,调试权限被清0 2,文件权限问题 其中看到很多解决方案中提到"重启电脑"的说法.我也试了几次不行甚至游戏都卸载了.后来 ...
- Electron笔记
一个能让你用Web技术开发桌面应用的开源项目.这里做一个笔记(非正式文章): 官网地址:http://electron.atom.io/ API相关 Electron提供的主进程接口.渲染进程接口.共 ...
- AdaBoost算法实现
# -*- coding: utf-8 -*- # -------------------------------------------------------------------------- ...
- atitit.userService 用户系统设计 v4 q316 .doc
atitit.userService 用户系统设计 v4 q316 .doc 1. 新特性1 2. Admin login1 3. 用户注册登录2 3.1. <!-- 会员注册使用 --> ...
- Kotlin:Android世界的Swift
转自:http://www.infoq.com/cn/news/2015/06/Android-JVM-JetBrains-Kotlin Kotlin是一门与Swift类似的静态类型JVM语言,由Je ...