
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、全面解析java的垃圾回收机制java的堆是一个运行时数据区,类的实例(对象)从中分配空间。java虚拟机(jvm)的堆中储存着正在运行的应用程序所建立的全部对象,这些对象通过new、newarray、anewarray和multianewarray等命令建立,但是它们不需要程序代码来显式地释放。普通来说,堆的是由垃圾回收来负责的,尽管jvm规范并不要求特别的垃圾回收技术,甚至根本就不需要垃圾回收,但是因为内存的有限性,jvm在实现的时候都有一个由垃圾回收所管理的堆。垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,根据特定的垃圾收集算法来实现资源自动回收的功能。 垃圾收集的意
2、义 在c+中,对象所占的内存在程序结束运行之前向来被占用,在明确释放之前不能分配给其它对象;而在java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。jvm的一个系统级线程会自动释放该内存块。垃圾收集意味着程序不再需要的对象是无用信息,这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占据的空间,以便空间被后来的新对象用法。实际上,除了释放没用的对象,垃圾收集也可以清除内存记录碎片。因为创建对象和垃圾收集器释放丢弃对象所占的内存空间,内存会浮现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片收拾将所占用的堆内存移到堆的一端,jvm将收拾出的内存分配给新的对象。
3、垃圾收集能自动释放内存空间,减轻编程的负担。这使java 虚拟机具有一些优点。首先,它能使编程效率提高。在没有垃圾收集机制的时候,可能要花许多时光来解决一个难懂的存储器问题。在用java语言编程的时候,靠垃圾收集机制可大大缩短时光。第二是它庇护程序的完整性, 垃圾收集是java语言平安性策略的一个重要部份。 垃圾收集的一个潜在的缺点是它的开销影响程序性能。java虚拟机必需追踪运行程序中实用的对象, 而且终于释放没用的对象。这一个过程需要花费处理器的时光。第二垃圾收集算法的不完备性,早先采纳的某些垃圾收集算法就不能保证100%收集到全部的废弃内存。固然随着垃圾收集算法的不断改进以及软硬件运行效
4、率的不断提升,这些问题都可以迎刃而解。 垃圾收集的算法分析 java语言规范没有明确地解释jvm用法哪种垃圾回收算法,但是任何一种垃圾收集算法普通要做2件基本的事情:(1)发觉无用信息对象;(2)回收被无用对象占用的内存空间,使该空间可被程序再次用法。 大多数垃圾回收算法用法了根集(root )这个概念;所谓根集就量正在执行的java程序可以拜访的引用变量的集合(包括局部变量、参数、类变量),程序可以用法引用变量拜访对象的属性和调用对象的办法。垃圾收集首选需要确定从根开头哪些是可达的和哪些是不行达的,从根集可达的对象都是活动对象,它们不能作为垃圾被回收,这也包括从根集间接可达的对象。而根集通过
5、随意路径不行达的对象符合垃圾收集的条件,应当被回收。下面介绍几个常用的算法。 1、 引用计数法(referee counting collector) 引用计数法是唯一没有用法根集的垃圾回收的法,该算法用法引用计数器来区别存活对象和不再用法的对象。普通来说,堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时,引用计数器置为1。当对象被赋给随意变量时,引用计数器每次加1当对象出了作用域后(该对象丢弃不再用法),引用计数器减1,一旦引用计数器为0,对象就满足了垃圾收集的条件。 基于引用计数器的垃圾收集器运行较快,不会长时光中断程序执行,相宜地必需 实时运行的程序。但引用计数器增
6、强了程序执行的开销,由于每次对象赋给新的变量,计数器加1,而每次现有对象出了作用域生,计数器减1。 2、acing算法(tracing collector) tracing算法是为了解决引用计数法的问题而提出,它用法了根集的概念。基于tracing算法的垃圾收集器从根集开头扫描,识别出哪些对象可达,哪些对象不行达,并用某种方式标志可达对象,例如对每个可达对象设置一个或多个位。在扫描识别过程中,基于tracing算法的垃圾收集也称为标志和清除(mark-and-sweep)垃圾收集器。 3、compacting算法(compacting collector) 为了解决堆碎片问题,基于tracin
7、g的垃圾回收汲取了compacting算法的思想,在清除的过程中,算法将全部的对象移到堆的一端,堆的另一端就变成了一个相邻的空闲内存区,收集器会对它移动的全部对象的全部引用举行更新,使得这些引用在新的位置能识别本来 的对象。在基于compacting算法的收集器的实现中,普通增强句柄和句柄表。 4、copying算法(co collector) 该算法的提出是为了克服句柄的开销和解决堆碎片的垃圾回收。它开头时把堆分成 一个对象 面和多个空闲面, 程序从对象面为对象分配空间,当对象满了,基于coping算法的垃圾 收集就从根集中扫描活动对象,并将每个 活动对象复制到空闲面(使得活动对象所占的内存
8、之间没有空闲洞),这样空闲面变成了对象面,本来的对象面变成了空闲面,程序会在新的对象面中分配内存。 一种典型的基于coping算法的垃圾回收是stop-and-copy算法,它将堆分成对象面和空闲区域面,在对象面与空闲区域面的切换过程中,程序暂停执行。 5、generation算法(generational collector) stop-and-copy垃圾收集器的一个缺陷是收集器必需复制全部的活动对象,这增强了程序等待时光,这是coping算法低效的缘由。在程序设计中有这样的逻辑:多数对象存在的时光比较短,少数的存在时光比较长。因此,generation算法将堆分成两个或多个,每个子堆作为
9、对象的一代(generation)。因为多数对象存在的时光比较短,随着程序丢弃不用法的对象,垃圾收集器将从最衰老的子堆中收集这些对象。在分代式的垃圾收集器运行后,上次运行存活下来的对象移到下一最高代的子堆中,因为老一代的子堆不会常常被回收,因而节约了时光。 6、adaptive算法(adaptive collector) 在特定的状况下,一些垃圾收集算法会优于其它算法。基于adaptive算法的垃圾收集器就是监控当前堆的用法状况,并将挑选适当算法的垃圾收集器。 透视java垃圾回收 1、行参数透视垃圾收集器的运行 2、用法system.gc()可以不管jvm用法的是哪一种垃圾回收的算法,都可以
10、哀求java的垃圾回收。 在指令行中有一个参数-verbosegc可以查看java用法的堆内存的状况,它的格式如下: java -verbosegc class 可以看个例子: class testgc public ic vo main(string args) new testgc(); system.gc(); system.runfinalization(); 在这个例子中,一个新的对象被创建,因为它没有用法,所以该对象快速地变为可达,程序编译后,执行指令: java -verbosegc testgc 后结果为: full gc 168k- 97k(1984k), 0.0253873
11、 secs 机器的环境为,windows 2000 + jdk1.3.1,箭头前后的数据168k和97k分离表示垃圾收集gc前后全部存活对象用法的内存容量,解释有168k-97k=71k的对象容量被回收,括号内的数据1984k为堆内存的总容量,收集所需要的时光是0.0253873秒(这个时光在每次执行的时候会有所不同)。 2、finalize办法透视垃圾收集器的运行 在jvm垃圾收集器收集一个对象之前 ,普通要求程序调用适当的办法释放资源,但在没有明确释放资源的状况下,java提供了缺省机制来终止化该对象心释放资源,这个办法就是finalize()。它的原型为: protect void fi
12、nalize() throws throwable 在finalize()办法返回之后,对象消逝,垃圾收集开头执行。原型中的throws throwable表示它可以抛出任何类型的异样。 之所以要用法finalize(),是因为有时需要实行与java的一般办法不同的一种办法,通过分配内存来做一些具有c风格的事情。这主要可以通过固有办法来举行,它是从java里调用非java办法的一种方式。c和c+是目前唯一获得固有办法支持的语言。但因为它们能调用通过其他语言编写的子程序,所以能够有效地调用任何东西。在非java代码内部,大概能调用c的malloc()系列函数,用它分配存储空间。而且除非调用了()
13、,否则存储空间不会得到释放,从而造成内存漏洞的浮现。固然,free()是一个c和c+函数,所以我们需要在finalize()内部的一个固有办法中调用它。也就是说我们不能过多地用法finalize(),它并不是举行一般清除工作的抱负场所。 在一般的清除工作中,为清除一个对象,那个对象的用户必需在希翼举行清除的地点调用一个清除办法。这与c+破坏器的概念稍有抵触。在c+中,全部对象都会破坏(清除)。或者换句话说,全部对象都应当破坏。若将c+对象创建成一个本地对象,比如在堆栈中创建(在java中是不行能的),那么清除或破坏工作就会在结束花括号所代表的、创建这个对象的作用域的末尾举行。若对象是用new创
14、建的(类似于java),那么当程序员调用c+的delete指令时(java没有这个指令),就会调用相应的破坏器。若程序员遗忘了,那么永久不会调用破坏器,我们终于得到的将是一个内存漏洞,另外还包括对象的其他部分永久不会得到清除。 相反,java不允许我们创建本地(局部)对象-无论如何都要用法new。但在java中,没有delete指令来释放对象,由于垃圾收集器会协助我们自动释放存储空间。所以假如站在比较简化的立场,我们可以说正是因为存在垃圾收集机制,所以java没有破坏器。然而,随着以后学习的深化,就会知道垃圾收集器的存在并不能彻低消退对破坏器的需要,或者说不能消退对破坏器代表的那种机制的需要(
15、而且肯定不能挺直调用finalize(),所以应尽量避开用它)。若希翼执行除释放存储空间之外的其他某种形式的清除工作,仍然必需调用java中的一个办法。它等价于c+的破坏器,只是没后者便利。 下面这个例子向大家展示了垃圾收集所经受的过程,并对前面的陈述举行了总结。 class chair static boolean gcrun = fae; static boolean f = false; static int created = 0; static int finalized = 0; int i; chair() i = +created; if(created = 47) syste
16、m.out.print(created 47); protected void finalize() if(!gcrun) gcrun = true; system.out.println(beginning to finalize after + created + chairs have been created); if(i = 47) system.out.println(finalizing chair 47, +setting flag to stop chair creation); f = true; finalized+; if(finalized = created) sy
17、stem.out.println(all + finalized + finalized); public class garbage public static void main(string args) if(args.length = 0) system.err.println(usage: n + java garbage beforen or:n + java garbage after); return; while(!chair.f) new chair(); new string(to take up space); system.out.println(after all chairs have been created:n + total created = + chair
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 基因递送效率提升-洞察及研究
- 柔性传感器多模态传感技术-洞察及研究
- 一次难忘的演讲经历演讲稿分享7篇
- 我最自豪的一次小小成就事件作文4篇范文
- 生物学遗传基因测试卷解析
- 我最尊敬的同学写人作文(6篇)
- 《初中化学分子式记忆技巧与练习课程》
- 澳洲签证面试题及答案
- 对老师表达敬意的抒情文7篇
- 记忆科技考试题及答案
- 物业承接查验办法培训
- 《大数据财务分析-基于Python》课后习题答案
- 里氏硬度法检测钢材强度范围记录表、钢材里氏硬度与抗拉强度范围换算表
- 动物病理(学)理论知识考核试题题库及答案
- 管理人员信息表-模板
- 人工挖孔桩 安全技术交底
- (新版)供电可靠性理论考试题库大全-下(填空题)
- 《护理人际沟通》全套教学课件
- 某冶金机械厂供配电系统设计
- 收费站年度工作计划
- xx县精神病医院建设项目可行性研究报告
评论
0/150
提交评论