关于垃圾回收被误解的 7 件事

(点击上方公众号,可快速关注)

ImportNew - 蒋 生武

对Java垃圾回收最大的误解是什么?它实际又是什么样的呢?

当我还是小孩的时候,父母常说如果你不好好学习,就只能去扫大街了。但他们不知道的是,清理垃圾实际上是很棒的一件事。可能这也是即使在Java的世界中, 同样有很多开发者对GC算法产生误解的原因——包括它们怎样工作、GC是如何影响程序运行和你能对它做些什么。因此我们找到了Java性能调优专家Haim Yadid,并把名为Java performance tuning guide的文章发表在Takipi的博客上。

http://blog.takipi.com/java-performance-tuning-how-to-get-the-most-out-of-your-garbage-collector/?utm_source=blog&utm_medium=in-post&utm_content=gcmisconceptions&utm_campaign=java

带着对性能调优指南浓厚的兴趣,我们决定在这篇后续的博文中收集一些关于垃圾回收的流行观点,并且指出为什么它们完全是错误的。

来看看前7名:

1. 只有一个垃圾回收器

不,并且4也是错误的答案。HotSpot JVM一共有4个垃圾回收器:Serial, Parallel / Throughput. CMS, and the new kid on the block G1。别急,另外还有一些非标准的垃圾回收器和更大胆的实现,比如Shenandoah或 者其他JVM使用的回收器(C4——Azul开发的无停顿回收器)。HotSpot默认使用Parallel / Throughput回收器,但它常常不是你运行程序的最佳选择。比如CMS和G1会使GC停顿(GC pause)发生的频率降低,但是对于每次停顿所花费的时间,很可能比Parallel回收器更长。另一方面来说,在使用相同大小堆内存的情况下,Parallel回收器能带来更高的吞吐量。

结论:根据你的需求(可接受的GC停顿频率和持续时间)选择合适的垃圾回收器。

2. 并行(Parallel) = 并发(Concurrent)

一个GC周期(Garbage Collection cycle)可以以STW(Stop-The-World)的形式出现,这会发生一次GC停顿,也可以并发地执行从而无需暂停应用程序。更进一步来 讲,GC算法本身可以是串行的(单线程),也可以是并行的(多线程)。因此当我们提到并发的GC时,并不代表它是并行完成的,相反当提到串行GC时,也并 不意味着就一定会出现GC停顿。在GC的世界中,并发和并行是两个完全不同的概念。并发针对的是GC周期,而并行针对GC算法自身。

结论:垃圾回收的过程实际上有两步,启动GC周期和GC自身运行,这是不同的两件事。

3. G1能解决所有问题

经过一系列修正和改 进,Java 7中引入了G1回收器,它是JVM垃圾回收器中最新的组件。G1最大的优势就是解决了CMS中常见的内存碎片问题:GC周期会从老年代(Old Generation)中释放内存块,结果内存变得像瑞士奶酪那样千疮百孔,直到JVM对其无从下手了,才不得不停下来处理这些碎片。但是故事没这么简 单,某些情况下其他回收器可能比G1有更好的表现,这完全取决于你的需求。

结论:没有一个奇迹般的回收器能解决所有GC问题,你应该通过具体实验来选择合适的回收器。

4. 平均事务时间是最需要被关注的指标

如 果你仅仅监控服务器的平均事务时间,那么很可能错过一些异常值。这些异常的情况可能对用户来说是毁灭性的,而人们没有意识到它的重要性。比如一个事务在正常情况下耗时100ms,但受到GC停顿的影响,花了1分钟才完成。除了用户没人会注意到这个问题,因为你只观察了平均事务时间。试想有1%或者更多的用 户经历了这个场景,如果只关注平均值,它就太容易被忽略了。想了解更多和延迟相关的问题和怎样正确处理,可以在这里阅读Gil Tene的博客。

http://latencytipoftheday.blogspot.com/

结论:留心那些异常值,你可以知道系统最后那1%的状况。(可不是这个1%)

5. 降低新对象的分配率可以改善GC的运行状况

我们可以 粗略地把系统中的对象分为三种:长命(long-lived)对象,对它们我们一般做不了什么;中等寿命(mid-lived)对象,最大的问题可能出现在这;短命(short-lived)对象,它们的释放和回收通常都很快,在下个GC周期来临时就会消失。专注于中等寿命对象的分配率可以带来有益的结 果,这对短命和长命的对象却不是那么有效。另外,控制中等寿命对象往往是一项困难的工作。

结论:给服务器带来压力的并不单纯是对象的分配率,在运行过程中这些对象的种类才是一切麻烦的根源。

6. 调优可以解决所有事

如果你的程序需要保存大量被频繁修改的状态,对JVM堆内存进行调优就无法带来很好的收益。较长的GC停顿是不可避免的。一个解决办 法是对架构进行改善,保证一个对响应时间有决定性影响或者造成瓶颈的过程中,不包含大量状态。大量状态和响应能力是难以良好共存的,因此将它们分开处理才 是上上之选。

结论:不是所有的问题都可以通过调整JVM参数解决,有时你只需要回顾自己的绘图板。(译注:重新审视程序的设计)

7. GC日志会导致巨大的系统开销

简单来说,这是错的,尤 其在默认的日志配置下。日志数据是极为有价值的,Java 7中还引入了钩子来控制它们的大小,保证硬盘空间不被用尽。如果不收集GC日志,那么你会失去这几乎是唯一的,知晓JVM垃圾回收器在生产环境中工作状态 的方法。一般可接受的GC开销以5%作为上限,如果你能知道系统为GC停顿付出的代价,也能对最小化这个代价采取行动,这种程度的开销是不值一提的。

结论:在能力范围内,尽可能多地获取系统在生产环境中的运行数据,你会发现那是一个全新的世界。

总结

希望上面的结论能帮助你们更好地把握Java垃圾回收器的工作。

原文发布于微信公众号 - 精讲JAVA(toooooooozi)

原文发表时间:2017-12-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏带你撸出一手好代码

做人肉代码翻译器是什么感受?

程序员编码的常规流程是通过大脑把将要实现的功能切分成一个个逻辑单元,使用编程语言将这些逻辑单元实现并组织在一起,积少成多, 形成电脑软件 缺乏经验的程序员可能...

39880
来自专栏七夜安全博客

《撸轮子系列》之LoadPE

18250
来自专栏CSDN技术头条

通过Temboo实现从Arduino获取雅虎天气信息

如果问我未来的科技行业发展有哪些亮点的话,我必须说物联网一定是其中之一。物联网技术发展迅速,现在我们已经看到非常多的设备通过互联网互相通信了。物联网技术的发展背...

24180
来自专栏腾讯Bugly的专栏

关于 Android N 那些你不知道的事儿

今年3月,Google 破天荒提前半年发布了 Android N 开发者预览版。当然,作为一个不合格的谷粉并没有第一时间体验安装,因为至今仍然能够回忆起来去年今...

35760
来自专栏华章科技

一个专家眼中的Go与Java垃圾回收算法大对比

我最近看过一堆宣传 Go 语言的最新垃圾收集器的文章。 其中一些文章来自 Go 项目本身。 他们声称 GC 技术发生了根本性的突破。

32450
来自专栏我和PYTHON有个约会

大牧夜话——爬虫篇-预告片PYTHON爬虫-江湖夜话

应大家的要求,最近打算整理一下PYTHON爬虫的东东,希望能对入门的童鞋们有所助益!本人技术一般水平有限,如有不妥请联系或者私信本人,互相进步。 内容会同步在...

10220
来自专栏企鹅号快讯

浅淡Python-初学者不得不说的秘密

不知道大家是否知道,Python的出现其实很偶然,是著名的“龟叔”Guido vanRossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言...

27650
来自专栏程序人生

上帝说:要有一门面向未来的语言,于是有了 erlang

今个谈谈 erlang。 这些文章流于表面,更多是简单的介绍。这篇文章不同,因为 erlang 并不是一门新语言,简单介绍它的人不算少,我希望这篇文章能在深度上...

416110
来自专栏我是攻城师

关于垃圾回收被误解的7件事

37890
来自专栏老九学堂

【超详细】20K以上的高薪Java程序员所需技能大汇总

总所周知,Java是目前使用最为广泛的网络编程语言之一。 它具有简单,面向对象,稳定,与平台无关,解释型,多线程,动态等特点。 一般的JAVA程序员或许只需知...

40940

扫码关注云+社区

领取腾讯云代金券