JVM常见垃圾回收算法
jdk1.7.0_79
众所周知,Java是一门不用程序员手动管理内存的语言,全靠JVM自动管理内存,既然是自动管理,那必然有一个垃圾内存的回收机制或者回收算法。本文将介绍几种常见的垃圾回收(下文简称GC)算法。
在Java堆上分配一个内存给实例对象时,此时在虚拟机栈上引用型变量就会存放这个实例对象的起始地址。
Object obj = new Object();
现在如果我们将变量赋值为null。
obj = null;
此时可以看到Java堆上的实例对象无法再次引用它,那么它就是被GC的对象,我们称之为对象“已死”。那虚拟机栈上的obj变量呢?上文《JVM入门——运行时数据区》提到过,虚拟机栈是线程独占的,也就是说随着线程初始而初始,消亡而消亡,当线程被销毁后,虚拟机栈上的内存自然会被回收,也就是说虚拟机栈上的这块内存空间不在虚拟机GC范围。下图展示了垃圾回收的内存范围:
1.对象是否“已死”算法——引用计数器算法
对象中添加一个引用计数器,如果引用计数器为0则表示没有其它地方在引用它。如果有一个地方引用就+1,引用失效时就-1。看似搞笑且简单的一个算法,实际上在大部分Java虚拟机中并没有采用这种算法,因为它会带来一个致命的问题——对象循环引用。对象A指向B,对象B反过来指向A,此时它们的引用计数器都不为0,但它们俩实际上已经没有意义因为没有任何地方指向它们。所以又引出了下面的算法。
2.对象是否“已死”算法——可达性分析算法
这种算法可以有效地避免对象循环引用的情况,整个对象实例以一个树呈现,根节点是一个称为“GC Roots”的对象,从这个对象开始向下搜索并作标记,遍历完这棵树过后,未被标记的对象就会判断“已死”,即为可被回收的对象。
GC算法
1.标记-清除算法
等待被回收对象的“标记”过程在上文已经提到过,如果在被标记后直接对对象进行清除,会带来另一个新的问题——内存碎片化。如果下次有比较大的对象实例需要在堆上分配较大的内存空间时,可能会出现无法找到足够的连续内存而不得不再次触发垃圾回收。
2.复制算法(Java堆中新生代的垃圾回收算法)
此GC算法实际上解决了标记-清除算法带来的“内存碎片化”问题。首先还是先标记处待回收内存和不用回收的内存,下一步将不用回收的内存复制到新的内存区域,这样旧的内存区域就可以全部回收,而新的内存区域则是连续的。它的缺点就是会损失掉部分系统内存,因为你总要腾出一部分内存用于复制。
在上文《JVM入门——运行时数据区》提到过在Java堆中被分为了新生代和老年代,这样的划分是方便GC。Java堆中的新生代就使用了GC复制算法。在新生代中又分为了三个区域:Eden 空间、To Survivor空间、From Survivor空间。不妨将注意力回到这张图的左边新生代部分:
新的对象实例被创建的时候通常在Eden空间,发生在Eden空间上的GC称为Minor GC,当在新生代发生一次GC后,会将Eden和其中一个Survivor空间的内存复制到另外一个Survivor中,如果反复几次有对象一直存活,此时内存对象将会被移至老年代。可以看到新生代中Eden占了大部分,而两个Survivor实际上占了很小一部分。这是因为大部分的对象被创建过后很快就会被GC(这里也许运用了是二八原则)。
3.标记-压缩算法(或称为标记-整理算法,Java堆中老年代的垃圾回收算法)
对于新生代,大部分对象都不会存活,所以在新生代中使用复制算法较为高效,而对于老年代来讲,大部分对象可能会继续存活下去,如果此时还是利用复制算法,效率则会降低。标记-压缩算法首先还是“标记”,标记过后,将不用回收的内存对象压缩到内存一端,此时即可直接清除边界处的内存,这样就能避免复制算法带来的效率问题,同时也能避免内存碎片化的问题。老年代的垃圾回收称为“Major GC”。
JVM常见垃圾回收算法的更多相关文章
- jvm详情——3、JVM基本垃圾回收算法回收策略
JVM基本垃圾回收算法回收策略 引用计数(Reference Counting):比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的 ...
- JVM(九):垃圾回收算法
JVM(九):垃圾回收算法 在本文中,我们将从概念模型的角度探讨 JVM 是如何回收对象,包括 JVM 是如何判断一个对象已经死亡,什么时候在哪里进行了垃圾回收,垃圾回收有几种核心算法,每个算法优劣是 ...
- JVM G1垃圾回收算法简要介绍
JVM G1垃圾回收算法简要介绍 G1的特点 能够像CMS垃圾回收算法一样并发操作应用线程(潜台词:多核) 无需太长时间即可压缩空闲内存空间(潜台词:不会引起太多的GC停顿时间) 尽可能地让GC时长可 ...
- 深入理解JVM一垃圾回收算法
我们都知道java语言与C语言最大的区别就是内存自动回收,那么JVM是怎么控制内存回收的,这篇文章将介绍JVM垃圾回收的几种算法,从而了解内存回收的基本原理. 一.stop the world 在介绍 ...
- JavaGC垃圾回收机制和常见垃圾回收算法
Java GC是在什么时候,对什么东西,做了什么事情?” 什么位置:大部分在堆中,还有方法区!!方法区的垃圾收集主要回收两部分内容:废弃常量和无用的类,当满了之后同样触发FullGC, HotSpot ...
- 深入探究JVM之垃圾回收算法实现细节
@ 目录 前言 垃圾回收算法实现细节 根节点枚举 安全点 安全区域 记忆集和卡表 写屏障 并发的可达性分析 低延迟GC Shenandoah ZGC 总结 前言 本篇紧接上文,主要讲解垃圾回收算法的实 ...
- jvm的垃圾回收算法
一.对象存活判断判断对象是否存活一般有两种方式:1.引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收.此方法简单,无法解决对象相互循环引用的问题.2 ...
- jvm学习-垃圾回收算法(三)
垃圾回收算法 引用计数法 比较古老的一种垃圾回收算法.在java的GC并没有采用 增加一个引用 引用+1 减少一个引用引用减一 每次清除引用为0的的对象 缺点:不能回收循环引用的垃圾对象 标记清除 ...
- JVM中垃圾回收算法
GC 算法与种类 GC的概念 Garbage Collection 垃圾收集1960年 List 使用了GCJava中,GC的对象是堆空间和永久区 引用计数法 老牌垃圾回收算法通过引用计算来回收垃圾使 ...
随机推荐
- TOJ4101.Guess Game(TOJ means Tianjin University Online Judge)(dp的思想,但这道题目是假dp)
题意:你要从[1,n]这个n个数中猜出来规定的某个数,现在这个数未知,问你在最糟糕的情况下(但是你采用了最优的策略),你要猜多少次才能猜出这个数.现在有两种条件: 第一种:当你猜的数比指定的那个数小的 ...
- Libevent源码分析—event, event_base
event和event_base是libevent的两个核心结构体,分别是反应堆模式中的Event和Reactor.源码分别位于event.h和event-internal.h中 1.event: s ...
- 一个html页面传入参数到另一个html页面用js获取方法
没错使用以下函数就能够完整的获取到路径里的你想要的参数:function getURLParameter(name) { return decodeURIComponent((new RegExp(' ...
- javascript基础-DOM原理
解释清楚DOM原理并不是一件容易的事,但是任何一个前端工程师,都必须牢牢掌握它. DOM整体架构: 图解: DOM,即针对XML文档的应用程序编程接口(API).通俗一点说,HTML属于XML的一种, ...
- C#码农的大数据之路 - 使用C#编写MR作业
系列目录 写在前面 从Hadoop出现至今,大数据几乎就是Java平台专属一般.虽然Hadoop或Spark也提供了接口可以与其他语言一起使用,但作为基于JVM运行的框架,Java系语言有着天生优势. ...
- poj2069
poj2069 题意 求一个覆盖所有点的最小球体的半径.即求空间内一点到所有点的距离的最大值最小的点. 分析 模拟退火算法,但这道题竟然不用随机函数就能过了,主要体现了算法的渐近收敛性, 起始点随意取 ...
- Day1 - Python基础1 Python介绍、基本语法、流程控制习题集
1.打印Hello World! print("Hello World!") 或 name="你好,世界!" print(name) 2.声明变量:打印name ...
- python之路第一篇
一.python环境的搭建 1.window下环境的搭建 (1).在 https://www.python.org/downloads/ 下载自己系统所需要的python版本 (2).安装python ...
- JQuery树形目录插件Dynatree
最近做网页需要做一个树形目录功能.找了一下发现有很多JQuery插件都可以实现这个功能.选了一个自己觉得最满意的插件Dynatree做个学习笔记. 可以把静态的html转成树形目录,还可以动态创建添加 ...
- python网络爬虫之LXML与HTMLParser
Python lxml包用于解析html和XML文件,个人觉得比beautifulsoup要更灵活些 Lxml中的路径表达式如下: 在下面的表格中,我们已列出了一些路径表达式以及表达式的结果: 路径表 ...