java 垃圾回收手动回收

G1:垃圾优先

G1收集器是热点JVM中要实现的最新收集器。 自Java 7 Update 4以来,它一直是受支持的收集器。OracleGC团队也公开表示,他们对低暂停GC的希望是完全实现的G1。 这篇文章来自我之前的垃圾收集博客文章:

  1. GC热点概述 。
  2. 并行垃圾收集器 。
  3. 并发标记扫描 。

问题:大堆意味着长暂停时间

并发标记和扫描(CMS)收集器是当前推荐的低暂停收集器,但是不幸的是,其暂停时间随使用权区域中活动对象的数量而变化。 这意味着尽管使用较小的堆相对容易获得短暂的GC暂停,但是一旦开始使用10或100千兆字节的堆,时间就会开始增加。

CMS也不会“整理”其堆,因此在某个时间点您会遇到并发模式故障(CMF),从而触发完整的gc。 进入完整的gc场景后,您可以预期每千兆字节活动对象大约在1秒钟的时间内出现暂停。 使用CMS,您的100GB堆可能是等待1.5分钟的GC暂停滴答定时炸弹……

良好的GC调优可以解决此问题,但有时只会将问题推向前进。 并发模式故障和完整GC不可避免地会在足够长的时间范围内出现,除非您处在一小部分专门避免填充其使用期限的人员中。

G1堆布局

G1收集器试图通过将堆分成不同的区域来将单个集合的暂停时间与堆的整体大小分开。 每个区域的大小都是固定的,介于1MB和32MB之间,JVM的目标是总共创建大约2000个区域。

您可能还记得以前的文章,其他收集器将堆分为Eden,Survior Space和Tenured内存池。 G1保留相同类别的池,但不是将它们作为连续的内存块,而是将每个区域在逻辑上分类为这些池之一。

还有另一种类型的区域-巨大的区域。 这些对象用于存储大小比大多数对象大的对象,例如,很长的数组。 任何大于区域大小50%的对象都存储在巨大的区域中。 它们通过获取连续位于内存中的多个正常区域并将它们视为单个逻辑区域来工作。

记忆集

当然,如果您将不得不扫描整个堆以找出哪些对象被标记为活动对象,那么将堆分成多个区域毫无意义。 实现此目标的第一步是将区域分成称为卡的512字节段。 每张卡在卡标记表中都有一个1字节的条目。

每个区域都有一个关联的记忆集或RSet-这是已写入的卡集。 如果来自存储在卡中的另一个区域的对象指向该区域中的对象,则卡处于记忆集中。

每当增变器写入对象引用时,就会使用写屏障来更新已记住的集。 在内部,将记住的集合分为不同的集合,以便不同的线程可以在没有争用的情况下运行,但是从概念上讲,所有集合都是同一集合的一部分。

并发标记

为了识别哪些堆对象是活动的,G1执行活动对象的大部分并发标记。

  • 标记阶段标记阶段的目标是弄清楚堆中哪些对象是活动的。 为了存储哪些对象处于活动状态,G1使用了标记位图-堆中每64位存储一个位。 从所有对象的根部开始跟踪,并在标记位图中使用活动对象标记区域。 这主要是并发的,但是有一个类似于CMS的“ 初始标记暂停” ,其中应用程序被暂停并且跟踪根对象的第一级子级。 完成此操作后,重新启动线程。 G1需要对堆中存在的内容保持最新了解,因为不会在标记阶段的同一暂停中清理堆。
  • 标记阶段标记阶段的目标是使标记阶段中有关活动对象的信息保持最新。 首先要做的是确定何时进行标记。 由一定百分比的堆已满触发。 这是通过从标记阶段和此后的分配数量中获取信息来计算的,并告诉G1其是否超过了所需的百分比。 G1使用上述写屏障来记录对堆的更改,并将其存储在一系列更改缓冲区中 。 更改缓冲区中的对象同时在标记位图中标记。 当达到填充百分比时,将再次暂停更改程序线程并处理更改缓冲区,从而将更改缓冲区中的对象标记为活动状态。
  • 清理阶段此时,G1知道哪些对象处于活动状态。 由于G1专注于可用空间最大的区域,因此其下一步是通过计算活动对象来计算给定区域中的可用空间。 这是从标记位图计算得出的,然后根据最有可能收集哪些区域来对区域进行排序。 要收集的区域存储在所谓的收集集或CSet中

疏散

与半球年轻一代在并行GC和CMS收集器中采用的方法类似,不会收集死物。 取而代之的是,将有生命的物体从某个区域撤离,然后将整个区域视为空闲区域。

G1对于如何回收活动物体很聪明–它不会尝试在给定的周期内回收所有活动物体。 它针对的是可能会回收尽可能多空间的区域,仅将其撤离。 它通过计算活动对象在一个区域内的比例并选择活动对象比例最低的区域来确定其目标区域。

将物体从多个其他区域撤离到自由区域。 这意味着G1在执行GC时会压缩数据。 这由多个线程并行操作。 传统的“平行GC”可以做到这一点,而CMS不这样做。

与CMS和Parallel GC相似,存在权属概念。 也就是说,如果年轻对象在足够的收藏中存活下来,它们就会变“旧”。 此数字称为任职期限。 如果年轻的世代区域幸存下来,并且保留了足够的活物以避免被疏散,那么该区域将得到提升。 首先是幸存者,最后是终身制地区。 它从未被疏散。

疏散失败

不幸的是,G1仍然会遇到类似于并发模式故障的情况,在这种情况下,它会退回到Stop the World Full GC。 这称为疏散失败,在没有空闲区域时发生。 没有自由区域意味着没有地方疏散物体。

从理论上说,与CMS中的并发模式故障相比,G1中发生疏散失败的可能性较小。 这是因为G1会即时压缩其区域,而不仅仅是等待压缩失败。

结论

尽管进行了压缩和在低暂停时做出的努力,但G1并不能保证会取得成功,因此采用它的任何尝试都应伴随有客观且可衡量的性能目标以及GC Log分析。 所需的方法超出了本博客文章的范围,但希望我在以后的文章中介绍它。

从算法上讲,G1会遇到其他Hotspot收集器不会遇到的开销。 值得注意的是,维护记忆集的成本。 并行GC仍然是推荐的吞吐量收集器,并且在许多情况下CMS都比G1更好。

现在说G1是否会比CMS收集器大胜还为时过早,但是在某些情况下,它已经为使用它的开发人员提供了好处。 随着时间的流逝,我们将看到G1的性能限制是否真的是G1的限制,或者开发团队是否只是需要更多的工程工作来解决那里的问题。

感谢John Oliver , Tim Monks和Martijn Verburg审阅了本指南和以前的GC文章的草稿。

参考: Insightful Logic博客上来自我们JCG合作伙伴 Richard Warburton的Java垃圾收集(4) 。

翻译自: https://www.javacodegeeks.com/2013/07/garbage-collection-in-java-4.html

java 垃圾回收手动回收

java 垃圾回收手动回收_Java垃圾回收(4)相关推荐

  1. java垃圾回收根对象_Java垃圾回收怎么理解?

    展开全部 Java的堆是一个运行时数据区,类的实例(对象)从中62616964757a686964616fe58685e5aeb931333339653664分配空间.Java虚拟机(JVM)的堆中储 ...

  2. java垃圾回收 分代_Java 垃圾回收机制 (分代垃圾回收ZGC)

    什么是自动 自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制.所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象:而未使用中的对象(未引用对象), ...

  3. java gc回收机制种类_Java垃圾回收机制

    对象被判定为垃圾的算法 引用计数算法 和 可达性分析算法 引用计数算法 判断对象的引用数量通过判断对象的引用数量来决定对象是否可以被回收 每个对象实例都有一个引用计数器,被引用+1,完成引用-1 任何 ...

  4. java 垃圾回收手动回收_Java垃圾回收(2)

    java 垃圾回收手动回收 并行清理 今天,我们介绍了并行GC的工作原理. 具体来说,这是在Eden上运行并行Scavenge收集器,在Tenured一代上运行Parallel Mark and Sw ...

  5. java 强制垃圾回收_Java垃圾回收机制

    Java垃圾回收机制 垃圾回收机制用到finalize.当程序创建对象.数组等引用类型实体时,系统都会在堆内存中为之分配一块内存区,对象就保存在这块内存中,当这块内存不再被任何引用变量引用时,这块内存 ...

  6. java gc会回收类么_Java GC 垃圾回收机制

    一.Java GC是什么? Java垃圾回收是对JVM(Java Virtual Machine)中的内存进行标记,并确定哪些内存需要回收,根据一定的回收策略,自动的回收内存,永不停息(Nerver ...

  7. 物品回收平台java代码_java垃圾回收

    jvm何时回收一个java对象所占的内存? 当java对象失去引用时,JVM垃圾回收机制会清除他们,回收所占内存空间. java有没有内存泄漏? 无用的内存没有被回收就是内存泄漏. C++内存泄漏:内 ...

  8. java与c内存管理_Java基础--Java内存管理与垃圾回收

    Java自动内存管理 在讲解内存管理之前,首先需要了解对象和对象引用的区别 对象是类的一个实例,以人这个类为例,Person是我们定义的一个类 public class Person{} public ...

  9. java垃圾回收菜鸟_java垃圾回收机制

    1:对象可能不被垃圾回收 2:垃圾回收并不等于"析构" 3:垃圾回收只与内存有关,为了回收程序不再使用的内存 java虚拟机采用了"自适应"的垃圾回收机制,即& ...

最新文章

  1. C#使用SQL语句时候的万用密码问题
  2. CentOS6.4安装gvim
  3. vue element 框架 自定义轮播图,点击上下翻图,并让图片居中
  4. 经典的Java面试题及回答集锦
  5. jdbc Template 介绍和 spring 链接数据源的四种方式
  6. crontab 每分钟一次_Celery实现定时任务crontab
  7. XX(北京)科技股份公司为啥需要购置服务器?
  8. 从零搭建angular环境和初项目
  9. Spring 源码解析 -- SpringWeb过滤器Filter解析
  10. Redis-数据结构06-快速链表(quicklist)
  11. Atitit. 解决80端口 System 占用pid 4,,找到拉个程序或者服务占用http 80服务
  12. ubuntu 安装openproj-1.4-2.noarch.rpm
  13. 2019ug最新版本是多少_UGNX将在2019年发布最新版本,让人更意想不到的是它的这项新功能!...
  14. CAD出图、标书装订、晒图、工程复印、彩色打印/复印
  15. 微信支付分终于开放了,你的支付分有600分吗?
  16. 如何关闭华为自动杀进程_如何彻底关闭windows 10的 自动更新
  17. Java开发高频英语单词800+,熟悉后英文障碍又少了
  18. 1187:统计字符数
  19. python 杀死线程_如何杀死正在运行的线程
  20. java的一些基础知识(引用BlogJava 落花飞雪)

热门文章

  1. 6、java中的排序算法
  2. Sentinel(十四)之控制台
  3. SpringBoot2.1.9 Mybatis由于@Mapper注解多数据源配置不生效问题
  4. 汇编语言(二十三)之求一个数的补数
  5. Oracle入门(十四.13)之带参数的游标
  6. Maven精选系列--标准目录结构
  7. Spring思维导图,让Spring不再难懂(mvc篇)
  8. 2020蓝桥杯省赛---java---B---10(整数小拼接)
  9. 捕获异常VS抛出异常
  10. html5动画是什么,10个HTML5动画 让你忘掉Flash是啥(组图)