当前位置: 首页 > 科技观察

关于Java垃圾收集的7个误解

时间:2023-03-19 16:32:53 科技观察

对于Java垃圾收集最大的误解是什么?它实际上是什么样子的?小时候,爸爸妈妈常说,不好好读书,只能扫街。但他们不知道的是,清理垃圾其实很酷。也许这就是为什么即使在Java世界中,也有许多开发人员误解了GC算法-它们的工作原理、GC如何影响程序执行以及您可以采取什么措施。于是我们找到了Java性能调优专家HaimYadid,并在Takipi的博客上发表了一篇名为Java性能调优指南的文章。出于对性能调优指南的浓厚兴趣,我们决定在这篇后续博文中收集一些关于垃圾回收的流行观点,并指出它们完全错误的原因。来看看前7名:1.垃圾收集器只有一个No,4也是错误答案。HotSpotJVM一共有4个垃圾收集器:Serial,Parallel/Throughput。CMS,以及G1块上的新成员。不用担心,还有一些非标准的垃圾收集器和更大胆的实现,比如Shenandoah或其他JVM使用的收集器(C4——Azul开发的非暂停收集器)。HotSpot默认使用Parallel/Throughput收集器,但它通常不是您正在运行的程序的最佳选择。例如CMS和G1会降低GC停顿(GCpause)的频率,但是每次停顿所花的时间很可能比Parallel收集器要长。另一方面,在使用相同大小的堆内存的情况下,Parallel收集器可以带来更高的吞吐量。结论:根据您的需要(可接受的GC暂停频率和持续时间)选择合适的垃圾收集器。2.并行(Parallel)=并发(Concurrent)一个GC循环(GarbageCollectioncycle)可以以STW(Stop-The-World)的形式出现,会引起GC暂停,也可以在不暂停的情况下并发执行应用。此外,GC算法本身可以是串行的(单线程)或并行的(多线程)。因此,当我们提到并发GC时,并不意味着它是并行完成的。相反,当我们提到串行GC时,并不意味着必须有GC停顿。在GC世界里,并发和并行是两个完全不同的概念。并发针对的是GC循环,而并行针对的是GC算法本身。结论:垃圾回收的过程其实有两个步骤,启动GC循环和运行GC本身,这是两个不同的东西。3、G1可以解决所有问题经过一系列的修正和改进,Java7引入了G1收集器,它是JVM垃圾收集器中的最新组件。G1最大的优点是解决了CMS中常见的内存碎片问题:GC循环会从老年代(OldGeneration)释放内存块,结果内存变得千疮百孔,直到JVM没办法处理,只好停下来处理这些碎片。但故事并没有这么简单,其他收集器在某些情况下可能比G1表现更好,这完全取决于您的需求。结论:没有一个神奇的收集器可以解决所有的GC问题,你应该通过具体的实验来选择合适的收集器。4、平均交易时间是最需要关注的指标。如果只监控服务器的平均事务时间,很可能会漏掉一些异常值。这些不寻常的情况可能会在人们没有意识到其重要性的情况下对用户造成毁灭性的打击。比如一个事务在正常情况下需要100ms,但是由于GC暂停,需要1分钟才能完成。除了用户,没有人会注意到这一点,因为您只查看平均交易时间。想象一下,有1%或更多的用户经历过这种情况,如果只关注平均值,很容易错过。要了解有关延迟问题以及如何正确处理它们的更多信息,您可以在此处阅读GilTene的博客。结论:留意异常值,您可以了解系统最后1%的情况。(不是这个1%)5.降低新对象的分配率可以改善GC的运行。我们可以大致将系统中的对象分为三类:long-lived(长寿命)对象,我们一般不能做什么;中等寿命(mid-lived)的对象,最大的问题可能出现在这里;short-lived(短命)对象,它们的释放和回收通常很快,在下一个GC周期到来时就会消失。关注中期对象的分配率可以产生有益的结果,这对短期和长期对象的效果较差。此外,控制中期对象通常是一项困难的工作。结论:给服务器带来压力的不仅仅是对象的分配率,而是正在运行的对象的类型导致了所有的麻烦。6.调优可以解决一切如果你的程序需要保存大量频繁修改的状态,调优JVM堆内存并不会带来好的好处。长时间的GC暂停是不可避免的。一种解决方案是改进架构,以确保对响应时间具有决定性影响或造成瓶颈的流程不包含大量状态。大量的状态和响应不能很好地共存,所以将它们分开是最好的选择。结论:并非所有问题都可以通过调整JVM参数来解决,有时您只需要回顾一下您的绘图板。(译注:重新审视程序的设计)7.GC日志记录会造成巨大的系统开销简单来说,这是错误的,尤其是在默认的日志记录配置中。日志数据极其宝贵,在Java7中引入了hooks来控制其大小,以保证硬盘空间不被耗尽。如果你不收集GC日志,那么你将失去这几乎是了解生产环境中JVM垃圾收集器状态的唯一方法。一般可接受的GC开销是5%作为上限。如果您能知道系统中GC暂停的成本并采取措施将此成本降至最低,那么这种级别的开销不值一提。结论:尽可能多地获取有关系统在生产中如何运行的数据,您会发现这是一个全新的世界。总结希望以上的结论可以帮助大家更好的掌握Java垃圾收集器的工作。你的程序中是否出现过类似的问题?你们还有其他关于GC的常见误解吗?请在下方评论区留言。