JVM内存管理------GC算法精解(五分钟教你终极算法---分代搜集算法)

转载自   JVM内存管理------GC算法精解(五分钟教你终极算法---分代搜集算法)

引言

 

         何为终极算法?

         其实就是现在的JVM采用的算法,并非真正的终极。说不定若干年以后,还会有新的终极算法,而且几乎是一定会有,因为LZ相信高人们的能力。

         那么分代搜集算法是怎么处理GC的呢?

 

对象分类

 

         上一章已经说过,分代搜集算法是针对对象的不同特性,而使用适合的算法,这里面并没有实际上的新算法产生。与其说分代搜集算法是第四个算法,不如说它是对前三个算法的实际应用

         首先我们来探讨一下对象的不同特性,接下来LZ和各位来一起给这些对象选择GC算法。

         内存中的对象按照生命周期的长短大致可以分为三种,以下命名均为LZ个人的命名。

         1、夭折对象:朝生夕灭的对象,通俗点讲就是活不了多久就得死的对象。

             例子:某一个方法的局域变量、循环内的临时变量等等。

         2、老不死对象:这类对象一般活的比较久,岁数很大还不死,但归根结底,老不死对象也几乎早晚要死的,但也只是几乎而已。

             例子:缓存对象、数据库连接对象、单例对象(单例模式)等等。

         3、不灭对象:此类对象一般一旦出生就几乎不死了,它们几乎会一直永生不灭,记得,只是几乎不灭而已。

             例子:String池中的对象(享元模式)、加载过的类信息等等。

         

对象对应的内存区域

 

         还记得前面介绍内存管理时,JVM对内存的划分吗?

         我们将上面三种对象对应到内存区域当中,就是夭折对象和老不死对象都在JAVA堆,而不灭对象在方法区

         之前的一章中我们就已经说过,对于JAVA堆,JVM规范要求必须实现GC,因而对于夭折对象和老不死对象来说,死几乎是必然的结局,但也只是几乎,还是难免会有一些对象会一直存活到应用结束。然而JVM规范对方法区的GC并不做要求,所以假设一个JVM实现没有对方法区实现GC,那么不灭对象就是真的不灭对象了。

         由于不灭对象的生命周期过长,因此分代搜集算法就是针对的JAVA堆而设计的,也就是针对夭折对象和老不死对象

         

JAVA堆的对象回收(夭折对象和老不死对象)

 

          有了以上分析,我们来看看分代搜集算法如何处理JAVA堆的内存回收的,也就是夭折对象与老不死对象的回收。

          夭折对象:这类对象朝生夕灭,存活时间短,还记得复制算法的使用要求吗?那就是对象存活率不能太高,因此夭折对象是最适合使用复制算法的

          小疑问:50%内存的浪费怎么办?

          答疑:因为夭折对象一般存活率较低,因此可以不使用50%的内存作为空闲,一般的,使用两块10%的内存作为空闲和活动区间,而另外80%的内存,则是用来给新建对象分配内存的。一旦发生GC,将10%的活动区间与另外80%中存活的对象转移到10%的空闲区间,接下来,将之前90%的内存全部释放,以此类推。

          为了让各位更加清楚的看出来这个GC流程,LZ给出下面图示。

         图中标注了三个区域中在各个阶段,各自内存的情况。相信看着图,它的GC流程已经不难理解了。

         不过有两点LZ需要提一下,第一点是使用这样的方式,我们只浪费了10%的内存,这个是可以接受的,因为我们换来了内存的整齐排列与GC速度。第二点是,这个策略的前提是,每次存活的对象占用的内存不能超过这10%的大小,一旦超过,多出的对象将无法复制

         为了解决上面的意外情况,也就是存活对象占用的内存太大时的情况,高手们将JAVA堆分成两部分来处理,上述三个区域则是第一部分,称为新生代或者年轻代。而余下的一部分,专门存放老不死对象的则称为年老代

         是不是很贴切的名字呢?下面我们看看老不死对象的处理方式。

         老不死对象:这一类对象存活率非常高,因为它们大多是从新生代转过来的。就像人一样,活的年月久了,就变成老不死了。

         通常情况下,以下两种情况发生的时候,对象会从新生代区域转到年老带区域。

         1、在新生代里的每一个对象,都会有一个年龄,当这些对象的年龄到达一定程度时(年龄就是熬过的GC次数,每次GC如果对象存活下来,则年龄加1),则会被转到年老代,而这个转入年老代的年龄值,一般在JVM中是可以设置的。

         2、在新生代存活对象占用的内存超过10%时,则多余的对象会放入年老代。这种时候,年老代就是新生代的“备用仓库”。

         针对老不死对象的特性,显然不再适合使用复制算法,因为它的存活率太高,而且不要忘了,如果年老代再使用复制算法,它可是没有备用仓库的。因此一般针对老不死对象只能采用标记/整理或者标记/清除算法

 

方法区的对象回收(不灭对象)

 

         以上两种情况已经解决了GC的大部分问题,因为JAVA堆是GC的主要关注对象,而以上也已经包含了分代搜集算法的全部内容,接下来对于不灭对象的回收,已经不属于分代搜集算法的内容。

         不灭对象存在于方法区,在我们常用的hotspot虚拟机(JDK默认的JVM)中,方法区也被亲切的称为永久代,又是一个很贴切的名字不是吗?

         其实在很久很久以前,是不存在永久代的。当时永久代与年老代都存放在一起,里面包含了JAVA类的实例信息以及类信息。但是后来发现,对于类信息的卸载几乎很少发生,因此便将二者分离开来。幸运的是,这样做确实提高了不少性能。于是永久代便被拆分出来了。

         这一部分区域的GC与年老代采用相似的方法,由于都没有“备用仓库”,二者都是只能使用标记/清除和标记/整理算法。

         

回收的时机

 

         JVM在进行GC时,并非每次都对上面三个内存区域一起回收的,大部分时候回收的都是指新生代。因此GC按照回收的区域又分了两种类型,一种是普通GC(minor GC),一种是全局GC(major GC or Full GC),它们所针对的区域如下。

         普通GC(minor GC):只针对新生代区域的GC。

         全局GC(major GC or Full GC):针对年老代的GC,偶尔伴随对新生代的GC以及对永久代的GC。

         由于年老代与永久代相对来说GC效果不好,而且二者的内存使用增长速度也慢,因此一般情况下,需要经过好几次普通GC,才会触发一次全局GC。

         

结束语

 

         GC的相关内容基本上就这些了,下一章我们一起探讨一下具体的GC实现都有哪些。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/328958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android 应用程序 判断 ,如何判断Android应用程序是否正在前台运行?

慕的地6264312或者,您可以检查ActivityManager哪些任务正在按getRunningTasks方法运行。然后,检查返回的任务列表中的第一个任务(前景中的任务)是否是您的任务。这是代码示例:public Notification buildNotification(String arg0, Map arg1) …

在离线环境中使用.NET Core

0x00 写在开始 很早开始就对.NET Core比较关注,一改微软之前给人的印象,变得轻量、开源、跨平台。最近打算试着在工作中使用。但工作是在与互联网完全隔离的网络中进行的,因此就开始了在离线环境中部署.NET Core开发环境的尝试。总的来说还是…

java常量池技术

转载自 java常量池技术摘要: 简介 常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s "java"这种…

华为荣耀5a是android几,华为荣耀5a各版本区别 华为荣耀5a各版本 对比【图文】

一个多月前,华为发布了华为荣耀5a,相信不少人都对这部手机十分期待。这款产品主打Slogan是“青春好拍档”。延续了5系列的定位,不仅价格便宜还拥有不错的拍照及音质调教。那么华为荣耀畅玩5A有几个版本?各版本有什么区别?下面小编就带来华为…

.NET程序员走向高端必读书单汇总

如今程序开发工作越来越简单(丰富的API、智能的IDE、越来越多的开发框架),普通人通过简单的训练,通过组合和复制就能完成众多程序的功能。因此程序员这种过去高技术职业的代名词,现在却如此低贱,被称之为码农。借用微观经济学原理…

android roboguice2,Android快速开发框架 roboguice

//使用框架前class AndroidWay extends Activity {TextView name;ImageView thumbnail;LocationManager loc;Drawable icon;String myName;public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);name (TextVi…

java 为什么需要常量池

转载自 java 为什么需要常量池java中讲的常量池,通常指的是运行时常量池,它是方法区的一部分,一个jvm实例只有一个运行常量池,各线程间共享该运行常量池。 java内存模型中将内存分为堆和栈,其中堆为线程间共享的内存数…

.NET Core第三方开源Web框架YOYOFx

YOYOFx框架 YOYOFx是一个轻量级用于构建基于 HTTP 的 Web 服务,基于 .NET 和 Mono 平台。 本着学习的态度,造了这个轮子,也是为了更好的了解各个框架的原理和有点,还希望可以和大家多交流 。 GitHub:https://github.co…

JavaScript实现搜索框效果

要求&#xff1a;搜索框获取焦点的时候如果里面的内容是“请输入关键字”&#xff0c;则清空&#xff0c;否则不清空 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">…

JVM调优总结(1):一些概念

转载自 JVM调优总结&#xff08;1&#xff09;&#xff1a;一些概念数据类型Java虚拟机中&#xff0c;数据类型可以分为两类&#xff1a;基本类型和引用类型。基本类型的变量保存原始值&#xff0c;即&#xff1a;他代表的值就是数值本身&#xff1b;而引用类型的变量保存引用…

android通讯录增删改查,android 通话记录的增删改查 .

//获取当前的手机号public String getLocalNumber() {Context context getApplicationContext();TelephonyManager tManager (TelephonyManager)context.getSystemService(TELEPHONY_SERVICE);String number tManager.getLine1Number();return number;}//删除通话记录privat…

使用C#进行系统编程

虽然对于系统编程&#xff08;System programming&#xff09;的定义很模糊&#xff0c;不过可以将其描述为在比特、字节、指令&#xff0c;或CPU周期层面所进行的思考。系统编程这个概念也暗含了对性能和可靠性的需求。Microsoft技术总监Joe Duffy在QCon New York活动中介绍了…

html表格转换为csv,python实现将html表格转换成CSV文件的方法

python实现将html表格转换成CSV文件的方法发布于 2015-11-18 16:53:39 | 155 次阅读 | 评论: 0 | 来源: 网友投递Python编程语言Python 是一种面向对象、解释型计算机程序设计语言&#xff0c;由Guido van Rossum于1989年底发明&#xff0c;第一个公开发行版发行于1991年。Pyth…

JVM调优总结(2):基本垃圾回收算法

转载自 JVM调优总结&#xff08;2&#xff09;&#xff1a;基本垃圾回收算法可以从不同的的角度去划分垃圾回收算法&#xff1a; 按照基本回收策略分 引用计数&#xff08;Reference Counting&#xff09;: 比较古老的回收算法。原理是此对象有一个引用&#xff0c;即增加一个…

巧妙使用信用卡N个小技巧

大家看标题也看出来了&#xff0c;今天的博文与之前的相差十万八千里&#xff0c;既不是代码&#xff0c;也不是黑科技&#xff0c;既不属于创业&#xff0c;也不属于赚钱&#xff0c;今天咱们坐下来就慢慢的谈谈信用卡吧&#xff0c;现在大多数白领&#xff0c;老板&#xff0…

ubuntu16.4下用jexus部署asp.net core rtm

今天说下ubuntu 下部署asp.net core&#xff0c;不需要安装.net core sdk&#xff0c;自带运行时方式部署&#xff0c;利用jexus服务器转发请求到asp.net core. 1.部署准备环境 vmware虚拟机&#xff08;其他也可以&#xff09; ubuntu16.04镜像 2.发布环境 win10系统 vs2015 u…

html页面会出现浏览器崩溃,大规模WebGL应用引发浏览器崩溃的几种情况及解决办法...

我们使用Javascript写WebApp的时候&#xff0c;一般都不会考虑对象的生命周期&#xff0c;不太关注内存“泄露”的问题&#xff0c;依赖JS引擎的垃圾回收机制就可以运行的很好&#xff0c;基本上很少会出现浏览器崩溃的情况。但在Web端显示大规模三维模型的时候&#xff0c;内存…

细说SSO单点登录

什么是SSO&#xff1f; 如果你已知道&#xff0c;请略过本节&#xff01; SSO核心意义就一句话&#xff1a;一处登录&#xff0c;处处登录&#xff1b;一处注销&#xff0c;处处注销。即&#xff1a;在多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应…

java实现字符逆序输出

package cn.jbit.array;import java.util.Arrays;public class CharsSort {/*** 字符逆序输出*/public static void main(String[] args) {char[] chars new char[]{a,c,u,b,e,p,f,z};System.out.print("原字符序列&#xff1a;");for(int i 0; i < chars.lengt…

html5页面转场,基于HTML5 SVG的页面过渡切换效果

示例中使用了CSS Flexbox和CSS变量&#xff0c;不是所有的浏览器都支持这些新的CSS属性。该HTML5 SVG的页面过渡变形切换效果的基本HTML结构如下&#xff1a;d"M -44,-50 C -52.71,28.52 15.86,8.186 184,14.69 383.3,22.39 462.5,12.58 638,14 835.5,15.6 987,6.4 1194,1…