一种Java虚拟机实现内存垃圾回收的方法及装置制造方法
【专利摘要】本发明公开了一种Java虚拟机实现内存垃圾回收的方法及装置,包括监控系统的内存垃圾回收情况,JVM触发全局内存垃圾回收前,创建新的Java应用环境,将原Java应用系统环境的后续外部请求转发到新Java应用环境的JVM中。本发明在JVM触发全局内存垃圾回收前,即创建好新的JVM应用环境,以便将原JVM应用环境中的后续外部请求在全局内存垃圾回收前就转移至新的JVM中,从而消除了原JVM出现的“假死”现象对应用执行的影响,同时也提高了系统的可用性。
【专利说明】—种Java虚拟机实现内存垃圾回收的方法及装置
【技术领域】
[0001]本发明涉及内存垃圾回收技术,尤指一种Java虚拟机(JVM, Java VirtualMachine)实现内存垃圾回收的方法及装置。
【背景技术】
[0002]Java虚拟机(JVM, Java Virtual Machine)有分配内存的指令,却没有释放内存的指令。JVM自身负责决定如何释放、以及何时释放不再被应用系统引用的对象所占据的内存。通常,这个任务由JVM中的垃圾收集器来完成。垃圾收集器的主要作用就是按一定的内存垃圾回收算法,自动回收不再被引用的对象所占用的内存。此外,垃圾收集器也可能移动那些还在被引用的对象,以此减少内存碎片。JVM中的内存管理,实质上是通过不同的垃圾收集器来实现的。垃圾收集器是依据垃圾收集算法运行的系统线程。
[0003]目前,主要的内存垃圾回收(GC, Garbage Collection)算法大致包括标记-清除(mark-swe印)算法、复制算法、标记-整理算法等。不管采用哪种算法,都有一个问题,就是在做全局内存垃圾回收时,只有内存垃圾回收线程在工作,应用中所有其它线程会暂停工作,也就是说,此时系统会暂时停止响应外部请求,导致系统出现“假死”现象。在实时性有关的应用中,JVM最大的问题不在于它的性能,而在于它的垃圾收集器。基于目前的内存垃圾回收算法,JVM都会在某些时刻暂停下来,而且暂停的时间也是不确定的,从而造成“假死”现象,而这种“假死”现象会导致严重的问题。
[0004]JVM内存分为方法区、栈、堆、寄存器等,JVM在进行内存垃圾回收时,主要是针对“堆”这部分内存进行的。目前,商用JVM的垃圾收集大都采用分代收集(GenerationalCollection)算法。分代收集算法将堆分成两个或多个对象,对象按照生存期分组,每一个子堆为一“代”对象服务。垃圾收集器将从最年轻的子堆(这个子堆被称为新生代)中收集这些对象,如果一个对象经历了几次垃圾收集后仍然存活,那么,这个对象就成长为生存期更高的一代,当超过预设的生存期阈值时,该对象会被转移到另外一个子堆(这个子堆被称为老年代)中去。
[0005]分代垃圾回收算法实现包括次要垃圾回收(minor GC)和全局垃圾回收(fullGC),minor GC主要回收新生代的内存垃圾,且把到达一定生存期的对象转移到老年代,minor GC进行的频率较高;而full GC则同时回收新生代和老年代的内存垃圾。
[0006]分代收集可以应用于标记-清除算法、复制算法、标记-整理算法等。分代收集可以减少长时间的垃圾收集停滞的频率,或者缩短暂停时间,但是即便采用这种分代收集方法,JVM也会出现暂停时间,且可能在大多数情况下暂停时间较短,而在某一、二次情况下暂停时间比一般的垃圾收集器时间更长,进而引起“假死”现象。
[0007]目前,虽然提出了各种各样的垃圾回收算法,但就其实质而言,主要就是要完成两件任务:1)检测出垃圾对象;2)回收垃圾对象所使用的堆空间并归还给JVM。
[0008]为了防止上述“假死”现象,对于执行时间较长的全局内存垃圾回收,一般是采用内存调优方法。比如,减小分代内存中老年区内存大小以降低全局内存垃圾收集的执行时间,或增大老年区内存大小以减少全局内存垃圾收集的执行次数。但是,即使做了调优,有时也还是达不到要求,并有可能使系统暂停时间增大。
[0009]另一种防止“假死”现象的方法是,采用实时Java规范(RTSJ, Real-timeSpecification for Java)。RTSJ在普通的JVM中增加了新的内存区域,即永久内存(Immortal Memory)和作用域内存(Scoped Memory)。其中,永久内存中的对象一旦分配就一直存在,直到虚拟机退出,因此不会被作为垃圾回收;而作用域内存可以看作是临时性的永久内存,作用域内存也不会引起垃圾回收,但其只在某个范围内有效,离开该范围时,该作用域内存块作为一个整体将被释放掉。RTSJ提出的这些概念,大大降低了代码引起垃圾回收的机会,而且垃圾回收的时刻被限定在可预测的范围之内。RTSJ的问题是修改了普通Java的规范,适用范围受到了限制。而且RTSJ内存管理模式太复杂,对开发人员提出了很多要求和限制,比如开发人员需要指定实时任务使用的内存空间,还要防止对象在不同区域间的引用超出某些限制,且这种基于区域的内存管理方式需要随时检查不同区域间对象弓丨用的合法性,带来了很多额外的开销,降低了系统的可用性。
【发明内容】
[0010]为了解决上述技术问题,本发明提供了一种Java虚拟机实现内存垃圾回收的方法及装置,能够消除系统中的“假死”现象,提高系统的可用性。
[0011]为了达到本发明目的,本发明提供了一种Java虚拟机JVM实现内存回收的方法,包括:
[0012]监控系统的内存垃圾回收情况,JVM触发全局内存垃圾回收前,创建新的Java应用环境;
[0013]将原Java应用系统环境的后续外部请求转发到新Java应用环境的JVM中。
[0014]所述监控系统的内存垃圾回收情况为:按预设时间间隔T获取所有JVM对应的JVM内存使用情况。
[0015]所述JVM触发全局内存垃圾回收前为:
[0016]老年代已使用内存和全部内存的比例,大于预先设置的老年代已使用内存和全部内存的比例允许阈值;
[0017]或者,老年代垃圾碎片比例大于预先设置的老年代垃圾碎片比例允许阈值;
[0018]或者,老年代剩余空间大小与每次次要垃圾回收minor GC后从新生代到老年代的对象大小平均值的比值,小于预先设置的比率系数允许阈值。
[0019]在所述原Java应用系统环境的所有外部请求处理完后,该方法还包括:回收所述原Java应用系统环境。
[0020]本发明还提供一种Java虚拟机JVM实现内存回收的装置,至少包括监控单元、处理单元、负载均衡单元,以及存储有可分配的JVM环境的JVM资源库和存储有应用包的系统应用库;其中,
[0021]监控单元,用于对系统的内存垃圾回收情况进行监控,并在原Java应用环境中的JVM触发全局内存垃圾回收前,向处理单元输出切换通知;
[0022]处理单元,用于接收到来自监控单元的切换通知,向JVM资源库申请JVM,从系统应用库中获取即将触发全局内存垃圾回收的应用包;将获得的应用包部署到申请到的JVM以创建新的Java应用环境,并通知负载均衡单元;
[0023]负载均衡单元,用于在接收到来自处理单元的通知,将原Java应用系统环境的后续外部请求转发到新Java应用环境的JVM中。
[0024]所述处理单元,还用于在所述原Java应用系统环境的所有外部请求处理完后,回收所述原Java应用系统环境。
[0025]所述内存垃圾回收情况包括:内存垃圾回收的次数、内存垃圾回收运行时间、新生代回收次数、老年代回收次数、老年代内存已使用比例、老年代内存剩余大小、内存垃圾碎片比率及其它内存垃圾回收的相关信息。
[0026]所述监控单元,具体用于:
[0027]对系统的内存垃圾回收情况进行监控,并在老年代已使用内存和全部内存的比例,大于预先设置的老年代已使用内存和全部内存的比例允许阈值;或者,老年代垃圾碎片比例大于预先设置的老年代垃圾碎片比例允许阈值;或者,老年代剩余空间大小与每次minor GC后从新生代到老年代的对象大小平均值的比值,小于预先设置的比率系数允许阈值时,向处理单元输出切换通知。
[0028]与现有技术相比,本发明包括监控系统的内存垃圾回收情况,JVM触发全局内存垃圾回收前,创建新的Java应用环境;将原Java应用系统环境的后续外部请求转发到新Java应用环境的JVM中。本发明提供的技术方案,在JVM触发全局内存垃圾回收前,即创建好新的JVM应用环境,以便将原JVM应用环境中的后续外部请求在全局内存垃圾回收前就转移至新的JVM中,从而消除了原JVM出现的“假死”现象对应用执行的影响,同时也提高了系统的可用性。
[0029]本发明的其它特征和优点将在随后的说明书中阐述,并且,部分地从说明书中变得显而易见,或者通过实施本发明而了解。本发明的目的和其他优点可通过在说明书、权利要求书以及附图中所特别指出的结构来实现和获得。
【专利附图】
【附图说明】
[0030]附图用来提供对本发明技术方案的进一步理解,并且构成说明书的一部分,与本申请的实施例一起用于解释本发明的技术方案,并不构成对本发明技术方案的限制。
[0031]图1为本发明Java虚拟机实现内存垃圾回收的装置的组成结构示意图;
[0032]图2为本发明Java虚拟机实现内存垃圾回收的方法的流程图;
[0033]图3为本发明Java虚拟机实现内存垃圾回收的方法的实施例的流程图。
【具体实施方式】
[0034]为使本发明的目的、技术方案和优点更加清楚明白,下文中将结合附图对本发明的实施例进行详细说明。需要说明的是,在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互任意组合。
[0035]在附图的流程图示出的步骤可以在诸如一组计算机可执行指令的计算机系统中执行。并且,虽然在流程图中示出了逻辑顺序,但是在某些情况下,可以以不同于此处的顺序执行所示出或描述的步骤。
[0036]图1为本发明Java虚拟机实现内存垃圾回收的装置的组成结构示意图,如图1所示,至少包括监控单元、处理单元、负载均衡单元,以及存储有可分配的JVM环境的JVM资源库和存储有应用包的系统应用库,其中,
[0037]监控单元,用于对系统的内存垃圾回收情况进行监控,并在原Java应用环境中的JVM触发全局内存垃圾回收前,向处理单元输出切换通知。
[0038]监控单元可以监控包括内存垃圾回收的次数、内存垃圾回收运行时间、新生代回收次数、老年代回收次数、老年代内存已使用比例、老年代内存剩余大小、内存垃圾碎片比率及其它内存垃圾回收的相关信息。
[0039]处理单元,用于接收到来自监控单元的切换通知,向JVM资源库申请JVM,从系统应用库中获取即将触发全局内存垃圾回收的应用包;将获得的应用包部署到申请到的JVM以创建新的Java应用环境,并通知负载均衡单元。这里,JVM资源库和系统应用库为现有系统中的资源库。
[0040]负载均衡单元,用于在接收到来自处理单元的通知,将原Java应用系统环境的后续外部请求转发到新Java应用环境的JVM中。
[0041]所述处理单元,还用于在原Java应用系统环境的所有外部请求处理完后,回收原Java应用系统环境。具体实现属于本领域技术人员的惯用技术手段,这里不再赘述。
[0042]其中,应用环境的创建属于本领域技术人员的惯用技术手段,并不用于限定本发明的保护范围,这里不再赘述。这里强调的是,在JVM触发全局内存垃圾回收前,即创建好新的JVM应用环境,以便将原JVM应用环境中的后续外部请求在全局内存垃圾回收前就转移至新的JVM中,这样,就消除了原JVM出现的“假死”现象对应用执行的影响,同时也提高了系统的可用性。
[0043]图2为本发明Java虚拟机实现内存垃圾回收的方法的流程图,如图2所示,主要包括以下步骤:
[0044]步骤200:监控系统的内存垃圾回收情况,JVM触发全局内存垃圾回收前,创建新的Java应用环境。
[0045]本步骤中,监控系统的内存垃圾回收情况为:按预设时间间隔T获取所有监控范围内的JVM对应的JVM内存使用情况。
[0046]如果老年代已使用内存和全部内存的比例大于预先设置的老年代已使用内存和全部内存的比例允许阈值;或者,老年代垃圾碎片比例大于预先设置的老年代垃圾碎片比例允许阈值;或者,老年代剩余空间大小与每次minorGC后从新生代到老年代的对象大小平均值的比值,小于预先设置的比率系数允许阈值V,则判断出JVM即将触发全局内存垃圾回收,即JVM触发全局内存垃圾回收前。
[0047]Java应用环境的创建属于本领域技术人员的惯用技术手段,并不用于限定本发明的保护范围,这里不再赘述。这里强调的是,在JVM触发全局内存垃圾回收前,即创建好新的Java应用环境。
[0048]步骤201:将原Java应用系统环境的后续外部请求转发到新Java应用环境的JVM中。本步骤中,将原Java应用环境中的后续外部请求在全局内存垃圾回收前就转移至新的JVM中,这样,就消除了原Java应用环境中的JVM出现的“假死”现象对应用执行的影响,同时也提高了系统的可用性。
[0049]本发明方法还包括:在原Java应用系统环境的所有外部请求处理完后,回收原Java应用系统环境。
[0050]下面结合实施例对本发明的方法进行详细描述。图3为本发明Java虚拟机实现内存垃圾回收的方法的实施例的流程图,如图3所示,包括:
[0051]步骤300:本发明Java虚拟机实现内存垃圾回收的装置所在系统初始化,具体包括:
[0052]预先设置获取内存使用情况的时间间隔T ;每次minor GC后,从新生代到老年代的对象大小平均值M ;老年代剩余空间大小S与每次minor GC后从新生代到老年代的对象大小平均值M的比值为比率系数的允许阈值V;老年代已使用内存和全部内存的比例允许阈值R ;老年代垃圾碎片比例允许阈值G ;以及,构建虚拟机资源池和应用库。
[0053]步骤301:系统获取当前Java应用所在的JVM的标识id,并将其设置为vmid。
[0054]步骤302:系统根据预先设置获取内存使用情况的时间间隔T,判断是否需要进行内存监控,若未达到时间间隔T,则不需要,则结束本流程;否则继续执行步骤303。
[0055]步骤303:监控单元按照预先设置的时间间隔T,获取vmid对应的JVM的内存使用情况。
[0056]步骤304:监控单元判断vmid对应的JVM是否进行了 minor GC,若未进行,则返回步骤303,否则继续执行步骤305。
[0057]步骤305:系统修改从新生代到老年代的对象大小平均值M。即每次minor GC后,计算新生代转移到老年代的所有对象的大小的平均值,并将得到的平均值赋给修改后的从新生代到老年代的对象大小平均值M。
[0058]步骤306:系统获取老年代内存已使用比例r,当前老年代剩余空间大小S,垃圾碎片占用比例g。
[0059]步骤307:系统判断是否r>R,或者S/M〈V,或者g>G,若不满足,则返回步骤302 ;否贝U,如果其中一个满足,则继续执行步骤308。
[0060]步骤308:处理单元查看VM资源池中是否存在空闲JVM,如果没有空闲JVM,则输出告警信息并通知系统后结束本流程;如果有空闲JVM,则继续执行步骤309。
[0061]步骤309:处理单元从JVM资源池中申请JVM,从应用库中获取应用包。
[0062]步骤310:处理单元将获得的应用包部署到申请到的JVM中,以创建新的Java应用环境。
[0063]步骤311:处理单元获取新Java应用环境所在的JVM的id。
[0064]步骤312:系统将新应用环境所在的JVM的id赋值给vmid,并修改负载均衡单元的配置。即原有JVM完成已经派发的任务,新的任务派发至新的JVM中。
[0065]步骤313:负载均衡单元将原Java应用系统环境的后续外部服务请求转发到新Java应用系统环境中vmid对应的JVM。
[0066]步骤314:系统判断是否需要回收原Java应用环境,如果需要,则将原Java应用环境上的JVM回收到JVM资源池中,返回步骤302 ;如果不需要,直接返回步骤302。
[0067]虽然本发明所揭露的实施方式如上,但所述的内容仅为便于理解本发明而采用的实施方式,并非用以限定本发明。任何本发明所属领域内的技术人员,在不脱离本发明所揭露的精神和范围的前提下,可以在实施的形式及细节上进行任何的修改与变化,但本发明的专利保护范围,仍须以所附的权利要求书所界定的范围为准。
【权利要求】
1.一种Java虚拟机JVM实现内存回收的方法,其特征在于,包括: 监控系统的内存垃圾回收情况,JVM触发全局内存垃圾回收前,创建新的Java应用环境; 将原Java应用系统环境的后续外部请求转发到新Java应用环境的JVM中。
2.根据权利要求1所述的方法,其特征在于,所述监控系统的内存垃圾回收情况为:按预设时间间隔T获取所有JVM对应的JVM内存使用情况。
3.根据权利要求1所述的方法,其特征在于,所述JVM触发全局内存垃圾回收前为: 老年代已使用内存和全部内存的比例,大于预先设置的老年代已使用内存和全部内存的比例允许阈值; 或者,老年代垃圾碎片比例大于预先设置的老年代垃圾碎片比例允许阈值; 或者,老年代剩余空间大小与每次次要垃圾回收minor GC后从新生代到老年代的对象大小平均值的比值,小于预先设置的比率系数允许阈值。
4.根据权利要求1所述的方法,其特征在于,在所述原Java应用系统环境的所有外部请求处理完后,该方法还包括:回收所述原Java应用系统环境。
5.一种Java虚拟机JVM实现内存回收的装置,其特征在于,至少包括监控单元、处理单元、负载均衡单元,以及存储有可分配的JVM环境的JVM资源库和存储有应用包的系统应用库;其中, 监控单元,用于对系统的内存垃圾回收情况进行监控,并在原Java应用环境中的JVM触发全局内存垃圾回收前,向处理单元输出切换通知; 处理单元,用于接收到来自监控单元的切换通知,向JVM资源库申请JVM,从系统应用库中获取即将触发全局内存垃圾回收的应用包;将获得的应用包部署到申请到的JVM以创建新的Java应用环境,并通知负载均衡单元; 负载均衡单元,用于在接收到来自处理单元的通知,将原Java应用系统环境的后续外部请求转发到新Java应用环境的JVM中。
6.根据权利要求5所述的装置,其特征在于,所述处理单元,还用于在所述原Java应用系统环境的所有外部请求处理完后,回收所述原Java应用系统环境。
7.根据权利要求5所述的装置,其特征在于,所述内存垃圾回收情况包括:内存垃圾回收的次数、内存垃圾回收运行时间、新生代回收次数、老年代回收次数、老年代内存已使用比例、老年代内存剩余大小、内存垃圾碎片比率及其它内存垃圾回收的相关信息。
8.根据权利要求7所述的装置,其特征在于,所述监控单元,具体用于: 对系统的内存垃圾回收情况进行监控,并在老年代已使用内存和全部内存的比例,大于预先设置的老年代已使用内存和全部内存的比例允许阈值;或者,老年代垃圾碎片比例大于预先设置的老年代垃圾碎片比例允许阈值;或者,老年代剩余空间大小与每次minorGC后从新生代到老年代的对象大小平均值的比值,小于预先设置的比率系数允许阈值时,向处理单元输出切换通知。
【文档编号】G06F9/46GK103514102SQ201310511414
【公开日】2014年1月15日 申请日期:2013年10月25日 优先权日:2013年10月25日
【发明者】王少锋, 张云勇, 王笑帝, 刘明辉, 陶冶 申请人:中国联合网络通信集团有限公司