版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
回收,顾名思义,便是将已经分配出去的,但却不再使用的内存回收回来,以便能够再次分配。在Java虚拟机的语境下,指的是的对象所占据的堆空间。这里便涉及了一个关键的问题:如何辨别一个对象是存是亡?我们先来讲一种古老的辨别方法:(referencecounting)。它的做法是为每个对象添加一个计数器,用来统计指向该对象的个数。一旦某个对象的计数器为0,则说明该对象已经,便可以被回收了。它的具体实现是这样子的:如果有一个,被赋值为某一对象,那么将该对象的计数器+1。如果一个指向某一对象的,被赋值为其他值,那么将该对象的计数器-1。也就是说,我们需要截获所有的更新操作,并且相应地增减目标对象的计数器。洞,那便是无法处理循环对象。举个例子,假设对象a与b相互,除此之外没有其他指向a或者b。在这种情况下,a和b实际上已经死了,但由于它们的计数器皆不为0,在的心中,这两个对象还活着。因此,这些循环对象所占据的空间将不可回收,从而造成了内存泄目前Java虚拟机的主流回收器采取的是可达性分析算法。这个算法的实质在于将一系列GCRoots作为初始的存活对象合集(lieset),然后从该合集出发,探索所有能够被该集合到的对象,并将其加入到该集合中,这个过程我们也称之为标记(mark)。最终,未被探索到的对象便是的,是可以回收的。那么什么是GCRoots呢?我们可以暂时理解为由堆外指向堆内的,一般而言,GCRoots包括(但不限于)如下几种:JavaJNI已启动且未停止的Java可达性分析可以解决所不能解决的循环问题。举例来说,即便对象a和b相互,只要从GCRoots出发无法到达a或者b,那么可达性分析便不会将它们加入(将设置为null)或者漏报(将设置为未被过的对象)误报并没有什么,Java虚拟机至多损失了部分回收的机会。漏报则比较麻烦,因 象,则很有可能会直接导致Java虚拟机。怎么解决这个问题呢?在Java虚拟机里,传统的回收算法采用的是一种简单的方式,那便是Stop-the-world,停止其他非回收线程的工作,直到完成回收。这也就造成了回收所谓的暂停时间(GCpause)。Java虚拟机中的Stop-the-world是通过安全点(safepoint)机制来实现的。当Java虚Stop-the-worldStop-the-world的线程进行独占的工作。这篇博客[2]还提到了一种比较另类的解释:安全词。一旦回收线程喊出了安全词,其当然,安全点的初始目的并不是让其他线程停下,而是找到一个稳定的执行状态。在这个执行状态下,Jaa虚拟机的堆栈不会发生变化。这么一来,回收器便能够“安全”地执行可达性分析。举个例子,当Java程序通过JNI执行本地代码时,如果这段代码不Java对象、调用Java方法或者返回至原Java方法,那么Java虚拟机的堆栈不会发生改变,也就代表着这由于本地代码需要通过JNI的API来完成上述三个操作,因此Java虚拟机仅需在API的处进行安全点检测(safepointpoll),测试是否有其他线程请求停留在安全点里,便除了执行JNI本地代码外,Java线程还有其他几种状态:解释执行字节码、执行即时编译器生成的机器码和线程阻塞。阻塞的线程由于处于Java虚拟机线程调度器的掌控之下,因其他几种状态则是运行状态,需要虚拟机保证在可预见的时间内进入安全点。否则,回收线程可能长期处于等待所有线程进入安全点的状态,从而变相地提高了回收的暂停时间。对于解释执行来说,字节码与字节码之间皆可作为安全点。Java虚拟机采取的做法是,当执行即时编译器生成的机器码则比较复杂。由于这些代码直接运行在底层硬件之上,不受Java虚拟机掌控,因此在生成机器码时,即时编译器需要插入安全点检测,以避免机器码长时间没有安全点检测的情况。HotSpot虚拟机的做法便是在生成代码的方法出口以及非第一,安全点检测本身也有一定的开销。不过HotSpot虚拟机已经将机器码中安全点检测简化为一个内存操作。在有安全点请求的情况下,Java虚拟机会将安全点检测的内存所在的页设置为不可读,并且定义一个segfault处理器,来截获因该不可读内存而触发segfault的线程,并将它们挂起。第二,即时编译器生成的机器码打乱了原本上的对象分布状况。在进入安全点时,机器码还需提供一些额外的信息,来表明哪些寄存器,或者当前栈帧上的哪些内存空间存放着指向对象的,以便回收器能够枚举GCRoots。不过,不同的即时编译器插入安全点检测的位置也可能不同。以Graal为例,除了上述位除了回收之外,Java虚拟机其他一些对堆栈内容的一致性有要求的操作也会用到安全当标记完所有的存活对象时,我们便可以进行对象的回收工作了。主流的基础回收方式第一种是清除(sweep),即把对象所占据的内存标记为空闲内存,并记录在一个空闲列表(list)之中。当需要新建对象时,内存管理模块便会从该空闲列表中寻找空闲内存,并划分给新建的对象。清除这种回收方式的原理及其简单,但是有两个缺点。一是会造成内存碎片。由于Java虚(pointerbum)来做分配。而对于空闲列表,Java虚拟机则需要逐个列表中的第二种是压缩(compact),即把存活的对象到内存区域的起始位置,从而留下一段第三种则是(copy),即把内存区域分为两等分,分别用两个指针from和to来维护,并且只是用from指针指向的内存区域来分配内存。当发生回收时,便把存活的对象到to指针指向的内存区域中,并且交换from指针和to指针的内容。这种回点。在下一篇中我们会详细介绍Java虚拟机中回收算法的具体实现。Java虚拟机中的回收器采用可达性分析来探索所有存活的对象。它从一系列GCRoots出发,边标记边探索所有被的对象。为了防止在标记过程中堆栈的状态发生改变,JavaStop-the-world操作,暂停其他非回收线程。回收对象的内存共有三种方式,分别为:会造成内存碎片的清除、性能开销较大的压缩、以及堆使用效率较低的。独跑foo方法或者bar方法的时间,然后与合起来跑的时间比较一下。1//timejava///-//-//-//-publicclassSafepointTeststaticdoublesum=publicstaticvoidfoo()for(inti=0;i< ;i++)sum+= publicstaticvoidbar()for(inti=0;i<50_000_000;{new}}publicstaticvoidmain(String[]{newnew 27[1] [2] 归科技所有 不得售卖。页面已增加防盗追踪,将依法其上一 10|Java对象的内存布下一 12|回收(下言言godtrue置 6旭东置 茶 151:回收-工作就是回收,哪关键点回来了。什么是?这个需要分类 6疑问通过调整大小,使对象在其生命周期内都待在中。这样一来,MinorGC时就可以彩色的沙 51、假设A开始指向A1对象:A------>A1,按老师说的误报就是将A指向null:A--Leon for(inti=start;i<limit;i++)对于int类型的循环变量i,如果满足1)基于该循环变量的循环出口只有一个,即i<limit,2)循下限)为循环无关的,即limit应是循环
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度企业人力资源优化与培训服务合同3篇
- 2024年度版权许可合同服务内容扩展
- 2024年度船舶买卖与运输合同
- 2024年度企业服务销售劳动合同范本(2024版)
- 2024年度茶山养老养生项目合作合同
- 2024年度汽车租赁公司设备采购合同
- 2024年度知识产权许可合同的知识产权范围与许可方式
- 2024年度股权转让涉及知识产权保护合同2篇
- 2024年度互联网金融服务合同(理财、借贷、支付等)2篇
- 2024年度特质离婚财产分割协议书
- db11 7912011 文物建筑消防设施设置规范
- 《unit 2 you shouldnt be late.》课件小学英语外研社版一年级起点五年级上册 (2014年6月第1版)
- 一年级数学口算凑十法
- 破产流程图最新版本
- 病例报告表(样板)
- 《长方形和正方形的认识》(课件) 数学三年级上册
- 机井、管道评定表格
- 医健卫统一资源管理平台解决方案.docx
- 养殖场投资成本分析表格
- 灭火器检查记录表模板
- 在全县创建义务教育优质均衡改革发展示范区动员大会上的讲话
评论
0/150
提交评论