JavaRush /Java 博客 /Random-ZH /管理 Java 内存(并保存代码)的指南
pandaFromMinsk
第 39 级
Минск

管理 Java 内存(并保存代码)的指南

已在 Random-ZH 群组中发布
译者注:翻译这篇文章的愿望是在六月的一个清晨,在地铁车厢里半睡半醒地读完这篇文章后产生的。目标受众:刚踏入 Java 世界的人们,由于其基本技术背景或愿望的性质,非常渴望深入了解 Java 并学习所有“电动”过程。我确信对于阅读本文的人来说,这将是进入配置 JVM 和 GC 世界之旅的起点。顺风顺水!原始文章在这里 作为一名开发人员,您花费了无数的时间来清除 Java 应用程序中的错误并获得所需的性能。在测试过程中,您会注意到应用程序运行速度逐渐变慢,最后完全崩溃或只是表现出较差的性能。最终接受内存泄漏发生的事实。Java 的垃圾收集器会尽力处理这些泄漏。但面对这样的情况,能做的事情就有限了。您需要一些方法来识别内存泄漏调用、确定原因并了解 Java 垃圾收集器在影响整体应用程序性能方面的作用。

Java内存泄漏的主要症状

有多种症状表明应用程序存在内存泄漏问题。性能的轻微下降,而不是突然的应用程序故障,仅表明存在内存泄漏。该问题可能在每次运行期间发生,或者仅当应用程序开始处理大量数据时发生,或者相反,当您开始扩展应用程序时。一旦泄漏耗尽了所有可用的内存资源,应用程序可能会显示内存不足错误。如果您重新启动应用程序并希望得到最好的结果,您将遇到重复的崩溃,直到泄漏得到修复。一般来说,当对象引用累积而不是释放内存时,就会发生内存泄漏。它们占用所有可用内存,使应用程序无法访问其所需的资源。

配置错误表现为内存泄漏

在研究导致 Java 内存问题的情况并进行分析之前,您需要确保该研究与完全不同的问题无关。一些内存不足错误是由于各种错误(例如配置错误)而发生的。该应用程序可能堆内存不足,或者可能与系统上的其他应用程序冲突。如果您开始谈论内存不足问题,但无法找出导致泄漏的原因,请从不同的角度查看应用程序。你会发现需要对终结线程进行更改或增加永久代空间量,永久代空间是 JVM 内存的一个区域,用于存储 Java 类的描述和一些附加数据。

内存监控工具的好处

内存监视工具可以更好地了解 Java 应用程序对可用资源的使用情况。通过使用此软件,您可以进一步缩小内存泄漏和其他性能事件问题根源的搜索范围。这些工具分为多个类别,即使您正在处理内存泄漏,您也可能需要使用各种应用程序来找出如何正确标记问题以及出了什么问题。堆转储文件提供了分析 Java 内存所需的信息。在这种情况下,您需要使用两个工具:一个用于生成转储文件,另一个用于详细分析。该解决方案提供了有关应用程序所发生情况的详细信息。一旦该工具查明了可能出现问题的位置,就会缩小范围以发现事件的确切位置。而这段时间,是试错时间最长、心情最紧张的一段时间。内存分析器指出了代码中的几个问题,但您不能完全确定应用程序遇到了哪些问题。如果您仍然遇到相同的错误,请重新开始并解决另一个可能的错误。一次进行一项更改并尝试重复错误。您需要让应用程序运行一段时间才能重复错误情况。如果在第一次测试期间出现内存泄漏,请务必对应用程序进行负载测试。应用程序在处理少量数据时可能可以正常工作,但在处理大量数据时可能会再次抛出相同的错误。如果仍然出现相同的错误,您需要重新开始并寻找其他可能的原因。一旦应用程序完全运行,内存监控工具就会证明其有用性。您可以远程监控 JVM 性能并在开发人员深入研究问题之前主动检测故障情况并收集历史性能数据以帮助改进他们未来的编程技术并了解 Java 在重负载下的表现。许多解决方案包括“危险”警报模式或其他类似模式,以便开发人员可以立即知道出了什么问题。每个开发人员都不希望关键应用程序在生产过程中崩溃并在应用程序停机期间造成数万或数十万美元的损失,因此内存监控工具可以缩短开发人员的响应时间。内存监控应用程序允许您立即启动诊断过程,而不是要求您去找客户,因为没有人会告诉您到底发生了什么错误或应用程序生成了什么错误代码。如果您经常发现自己陷入 Java 应用程序的内存和性能问题中,请深入研究测试过程。确定开发过程中的每个薄弱环节并改变您的测试策略。咨询同事并将您的测试方法与现有的最佳实践进行比较。有时您需要修改一小段代码,然后确保对整个应用程序产生持久影响。

垃圾收集器对 Java 内存和内存泄漏的作用

Java 中的垃圾收集器在应用程序性能和内存使用方面起着关键作用。它查找未使用的(死的)对象并删除它们。这些对象不再占用内存,因此您的应用程序将继续确保资源可用性。有时,应用程序没有给 GC 足够的时间或资源来删除死对象,它们就会累积。您可能会遇到这样的情况:对您认为已死亡的对象进行主动访问。垃圾收集器对此无能为力,因为...... 它的自动内存管理机制绕过活动对象。通常,垃圾收集器会自主运行,但您需要调整其行为以应对严重的内存问题。然而,GC 本身可能会导致性能问题。

GC 区域

垃圾收集器将对象分成不同的区域以优化组装。年轻一代的特点是物体很快就会消亡。垃圾收集器从清理工作开始就经常在这个区域工作。达到一定期限后仍然存活的对象将被转移到老年代。在老一代区域,对象会保留很长时间,并且不会经常被收集器删除。但是,当收集器在作用域中运行时,应用程序会执行一项大型操作,其中收集器会查找活动对象以清理垃圾。结果,应用程序对象位于最终的永久生成区域中。通常,这些对象包括必要的 JVM 元数据。应用程序在永久生成中不会生成太多垃圾,但需要收集器在不再需要类时删除类。

垃圾收集器与响应时间的关系

无论应用程序线程的执行优先级如何,垃圾收集器都会停止它们而不等待完成。这种现象被称为“停止世界”事件。垃圾收集器的年轻代区域对性能影响较小,但如果 GC 进行密集清理,问题就会很明显。您最终会遇到这样的情况:年轻代 Minor GC 不断运行,或者老一代进入不受控制的状态。在这种情况下,您需要平衡年轻代频率与需要增加该收集器区域大小的性能。垃圾收集器的永久代和老一代区域对应用程序性能和内存使用有显着影响。这个主要的垃圾清理操作通过堆来推出死对象。该过程比次要构建需要更长的时间,并且性能影响可能需要更长的时间。当擦洗强度较高且老年代区域大小较大时,整个应用程序的性能会因“Stop the world”事件而陷入困境。优化垃圾收集需要监控程序运行的频率、对整体性能的影响以及如何调整应用程序设置以降低监控频率。您可能需要识别多次放置的同一对象,而应用程序不必将自己与放置隔离开来,或者您可能需要找到阻碍整个系统的压缩点。获得正确的平衡需要密切关注从 CPU 负载到垃圾收集器周期的所有方面,特别是在年轻代和老一代不平衡的情况下。解决内存泄漏和优化垃圾收集有助于提高 Java 应用程序的性能。您实际上是在处理许多移动部件。但是,通过正确的故障排除方法和旨在提供严格可见性的分析工具,您将到达隧道尽头的曙光。否则,您将遇到与性能相关的问题。仔细的内存放置和监控在 Java 应用程序中起着至关重要的作用。您需要完全控制垃圾收集、对象处理和性能之间的交互,以优化应用程序并避免内存不足错误。监控工具可帮助您掌握潜在问题并突出显示内存利用率趋势,以便您采取主动的方法进行故障排除。内存泄漏通常表明按常规方法进行故障排除是无效的,尤其是在遇到不正确的配置参数值的情况下,但解决与内存相关的问题可以帮助您快速避免发生妨碍您的事件。Java内存调优和GC的完善让你的开发过程变得更加轻松。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION