关于Java中的GC,简单来说就是垃圾收集器自动回收生命周期结束的对象,释放内存。

  那么怎样确定对象是否存活呢?

可达性分析算法

  现在主流的Java虚拟机大多使用这种可达性分析算法来判断对象是否需要进行垃圾回收。具体也就是,从GC Roots出发,向下搜索,形成一个完整的对象引用链。当某个对象没有任何到达GC Roots的引用链时,便认为这个对象的生命周期结束,是可以被回收的。

  

  GC Roots对象指的哪些呢?

    • 虚拟机栈中引用的对象
    • 元数据区中静态变量引用的对象
    • 元数据区中常量引用的对象
    • 本地方法栈中native方法引用的对象

分代回收算法

  现在的JVM大多使用分代回收算法,将堆内存分为新生代和老年代。对这两部分分别使用不同的回收算法。

  老年代中存放大对象和长期存活的对象,且对象较多,一般使用标记-清除算法或者标记-整理算法。新生代存活对象较少,一般使用复制算法。

标记-清除

  以可达性分析算法遍历所有引用,给活着的对象打上标记。遍历结束后,统一清除需要回收的对象。

  这种算法的缺点在于:

        1. 标记和清除的效率不高
        2. 进行清除以后,内存空间是不连续的。

  使用这种算法的虚拟机,在进行对象内存分配时,会维护一个内存空闲列表,记录哪些内存空间可用,再进行分配。

标记-整理

  与标记-清除类似,先进行标记,之后把活着的对象移动到一端,排在一起,最后清除需要回收的对象。这样的话,可以让内存地址是连续的。

  如果虚拟机使用这种算法进行GC的话,在为对象分配内存时,只需要按对象的大小进行指针移动,分配足够的空间便可。

复制算法

  一般在新生代中使用这种算法。将新生代内存分为一个Eden和两个Survivor区域,比例为8:1:1。

  在初始时,先把对象分配到较大的Eden区域。Eden区满以后,触发Minor GC,将活着的对象复制到一个Survivor区(假如为Survivor0),并且把对象年龄加1,然后清空Eden区。当Eden再次放满以后,再把Eden区和Survivor0中活着的对象复制到另一个Survivor区,加对象年龄,清空Eden区和Survivor0区。如此循环往复。如果对象年龄达到界限(默认15),视对象为长生命周期对象,移动到老年代。大对象在内存分配时,直接放到老年代,因为大对象做复制操作费效率。值得注意的是,在复制算法的过程中,如果空闲的Survivor区内存大小无法满足需要,会依赖老年代的空间进行担保。

  复制算法得到的内存空间同样是连续的。

浅谈GC的更多相关文章

  1. 【转】.NET(C#):浅谈程序集清单资源和RESX资源 关于单元测试的思考--Asp.Net Core单元测试最佳实践 封装自己的dapper lambda扩展-设计篇 编写自己的dapper lambda扩展-使用篇 正确理解CAP定理 Quartz.NET的使用(附源码) 整理自己的.net工具库 GC的前世与今生 Visual Studio Package 插件开发之自动生

    [转].NET(C#):浅谈程序集清单资源和RESX资源   目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...

  2. Android性能优化的浅谈

    一.概要: 本文主要以Android的渲染机制.UI优化.多线程的处理.缓存处理.电量优化以及代码规范等几方面来简述Android的性能优化 二.渲染机制的优化: 大多数用户感知到的卡顿等性能问题的最 ...

  3. 浅谈线程池(中):独立线程池的作用及IO线程池

    原文地址:http://blog.zhaojie.me/2009/07/thread-pool-2-dedicate-pool-and-io-pool.html 在上一篇文章中,我们简单讨论了线程池的 ...

  4. 浅谈线程池(上):线程池的作用及CLR线程池

    原文地址:http://blog.zhaojie.me/2009/07/thread-pool-1-the-goal-and-the-clr-thread-pool.html 线程池是一个重要的概念. ...

  5. 浅谈Android应用性能之内存

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 文/ jaunty [博主导读]在Android开发中,不免会遇到许多OOM现象,一方面可能是由于开 ...

  6. 浅谈开源项目Android-Universal-Image-Loader(Part 3.1)

    本文转载于:http://www.cnblogs.com/osmondy/p/3266023.html 浅谈开源项目Android-Universal-Image-Loader(Part 3.1) 最 ...

  7. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  8. VSTO学习笔记(九)浅谈Excel内容比较

    原文:VSTO学习笔记(九)浅谈Excel内容比较 说起文件内容比较,或许我们首先想到的是UltraCompare这类专业比较的软件,其功能非常强大,能够对基于文本的文件内容作出快速.准确的比较,有详 ...

  9. 浅谈java类集框架和数据结构(2)

    继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...

随机推荐

  1. [CSP-S模拟测试]:导弹袭击(数学+凸包+单调栈)

    题目背景 $Guess$准备向敌军阵地发起进攻了!$Guess$的武器是自动制导导弹.然而在机房是不允许游戏的,所以班长$XZY$对游戏界面进行了降维打击,结果... 题目描述 众所周知,环境因素对导 ...

  2. Java中使用Redis的几种数据类型总结

    1.String,最基本的类型 方法  set.get 2.hash redis 127.0.0.1:6379> HMSET user:1 username redis.net.cn passw ...

  3. Parse error: syntax error, unexpected 'class' (T_CLASS)

    电脑坏了重新下载代码. 结果报错 Parse error: syntax error, unexpected 'class' (T_CLASS), expecting identifier (T_ST ...

  4. loadrunner常用函数整理

    1.int web_reg_save_param("参数名","LB=左边界","RB=右边界",LAST);   //注册函数,在参数值出 ...

  5. 【后台管理系统】—— Ant Design Pro组件使用(一)

    一.搜索Search      搜索框 <Search placeholder="请输入关键字" defaultValue={kw && kw != 'nul ...

  6. C\C++语言中的宏多重展开和递归展开

    宏定义中的#,## 1. 宏中的参数前面使用一个#,预处理器会把这个参数转换为一个字符数组     2.记号粘贴操作符(token paste operator): ##            “## ...

  7. debugfs linux rm 删除 恢复 Attempt to read block from filesystem resulted in short read while opening filesystem

    w 删除具有空字符的文件 反斜杠来转义下一个字符 rm -R Samples\ -\ Copy well@well:/home/etc/project/apilinux/MarketplaceWebS ...

  8. 【C++进阶:STL常见性质3】

    STL3个代表性函数:for_each(), random_shuffle(), sort() vector<int> stuff; random_shuffle(stuff.begin( ...

  9. 抓包工具之—charles碎言碎语

    一.Charles常见使用场景: 1.Charles是跨平台的抓包工具,支持Windows,mac或Linux平台: 2.获取请求信息.测试接口时,若接口文档中的参数不清楚或没有接口文档时,可以通过抓 ...

  10. Common Linux Commands 日常工作常用Linux命令

      How to know CPU info      cat /proc/cpuinfo      arch   How to know memory info: cat /proc/meminfo ...