热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Java内存溢出的原因和解决方法

这篇文章主要介绍了Java内存溢出的原因和解决方法,帮助大家更好的维护Java程序,保持稳定性,感兴趣的朋友可以了解下

你是否遇到过Java应用程序卡顿或突然崩溃的情况?您可能遇到过Java内存泄漏。在本文中,我们将深入研究Java内存泄漏的确切原因,并推荐一些最好的工具来防止内存泄漏发生。

什么是JAVA内存泄漏?

简单地说,Java内存泄漏是指对象不再被应用程序使用,而是在工作内存中处于活动状态。

在Java和大多数其他编程语言中,垃圾收集器的任务是删除不再被应用程序引用的对象。如果不选中,这些对象将继续消耗系统内存,并最终导致崩溃。有时java内存泄漏崩溃不会输出错误,但通常错误会以java.lang.OutOfMemoryError

JAVA内存泄漏的原因是什么?

当未被引用的对象被归类为引用对象时,就会导致Java内存泄漏。这会阻止垃圾回收器清除内存,导致内存最终耗尽并崩溃。

在内存中,对象可以有两种状态,未引用和已引用。被引用的对象仍然具有到Java应用程序的活动连接,而未被引用的对象则没有。垃圾回收器的任务是查找和标识未引用的对象并将其删除。

垃圾回收器不会清理似乎被引用或正在使用的对象。Java内存泄漏发生在未引用的对象重叠时,这些对象似乎仍在使用中。

我怎么知道是否有内存泄漏?

有几种方法可以检查你的代码,看看它是否发生了内存泄漏。识别泄漏的最简单方法是查找java.lang.OutOfMemoryError错误日志中的事件。如果列出了此事件,您将能够提取有关Java的哪些部分导致了这种情况的进一步详细信息。

您经常会发现有关Java堆空间的详细信息。这可能意味着内存泄漏,资源无法分配,或者堆大小设置得太低。

通常也会发现标记为PermGen空间的错误。在大多数情况下,这不是内存泄漏,而是需要扩展的分配空间。永久生成空间用于存储类对象,如果不扩展,则可以填充。

并不是所有的Java内存泄漏都是相同的,有些漏洞可以比其他漏洞更容易预防。让我们来看看Java内存泄漏的一些最常见的原因。

如何防止JAVA内存泄漏

最常见的内存泄漏类型之一是Java中的对象随着时间的推移而创建,但从未释放。提高性能和防止内存泄漏的一个简单方法是检查代码中静态字段的使用情况。

当您将Java中的任何对象设置为静态时,它会自动将该对象的生命周期附加到JVM本身,因此垃圾收集器从不清除它。正如您可以想象的那样,如果您有许多大对象被设置为静态的,这会在您的代码中造成相当大的问题。

一定要检查static和collections的所有用法。这两者都是导致Java内存泄漏和意外占用内存的最常见原因。

Java内存泄漏的另一个常见原因是存在未关闭的连接。代码中保持连接打开而不关闭连接的任何部分都可能导致内存过度使用。未闭合连接最常见的罪魁祸首是http调用、stream流、FTP站点和数据库访问。

当保持打开状态时,连接会迅速导致堆内存膨胀,并最终导致应用程序崩溃。若要解决此问题,请始终确保在代码中指定了关闭连接的时间。

就像未关闭的连接一样,未关闭的流会导致非常类似的内存泄漏和资源问题。如果未选中,则打开的流将增加堆内存使用量,以达到临界级别,并最终崩溃。在旧版本的Java中,流必须手动关闭,但是现在使用try with resources语句,这可以自动实现。

虽然寻找这些具体的例子可能会有所帮助,但每个程序的编码都是不同的,需要采用不同的方法。如果您要手动查看代码,启用详细的垃圾收集可以帮助您更好地了解哪些内容正在被收集,哪些内容没有被收集。

添加-verbose:gc参数到配置将准确地输出垃圾收集工具正在执行的操作,并让您深入了解可能需要修改的内容。这是一个简单的技巧,但仍然需要你的时间和精力来筛选结果。

对代码进行可靠的审核还可以发现阻碍性能或导致内存泄漏的潜在问题。虽然这看起来很费时,但这通常是处理所有代码的最佳实践,并有助于避免严重的麻烦。

防止JAVA内存泄漏的工具

最后,为了更快地堵住内存泄漏,可以考虑使用Java分析器。探查器允许您监视特定的JVM参数,例如对象创建和垃圾回收。探查器甚至比详细模式更进一步,可以帮助突出显示需要数小时手动跟踪的内存和资源问题。

您可以使用诸如YourKit或JProfiler这样的Java探查器,不仅可以帮助您发现Java代码中的内存泄漏,还可以确定优化和改进的机会。YourKit和JProfiler都有助于删减不必要的代码并识别应用程序中的冗余。虽然这两个示例都不会导致内存泄漏,但它们会影响代码的性能。

JAVA Profiler可以提供以下功能:

  • 创建的所有对象
  • 所有方法的CPU时间
  • 执行期间创建的对象
  • 从内存中删除的对象
  • 垃圾收集信息

但是,使用一个好的Java分析器只是成功的一半;您还需要监视应用程序的运行状况,因为它会随着时间的推移而变化。为此,您需要将Java分析器与一个著名的Java性能工具配对。

您可以将Java探查器看作是一种反应式工具,而Java性能监视器则是一种主动式工具。您既要确保您的应用程序为您的用户以最佳方式运行,又要避免不必要的停机时间。Java性能监视工具可以测量应用程序的响应能力,监视sla,甚至可以根据用户数据计算许多不同的度量来跟踪用户体验。

我们花了一些时间来寻找一些最好的Java性能工具,可以用来帮助防止Java内存泄漏,并保持代码平稳运行。

以下是我们精选的最佳JAVA性能工具:

  • SolarWinds AppOptics(免费试用)提供多种应用程序的深度视觉效果和报告功能。
  • DataDog Java性能监控工具平衡了易用性,同时优先考虑了主动特性
  • VisualVM是一个简单的Java探查器,非常适合基本的故障排除。
  • JProfiler一种付费的Java评测器,可以检测不同级别的大量bug
  • Eclipse内存分析器MAT提供了Java堆内存的详细细分,以更好地了解内存泄漏。
  • Glowroot一个开源的性能监视器,通过本地浏览器显示数据。

1. SOLARWINDS APPOPTICS(免费试用)

SolarWinds公司的AppOptics是一款全服务的应用程序性能监视器,为大量不同的应用程序构建。虽然AppOptics支持许多程序,但它在监视和排除Java应用程序故障方面做得特别好。

与DataDog类似,AppOptics将强大的功能组合到一个易于使用的仪表板中,允许您自定义和控制您的监视体验。可以从头开始创建警报,也可以从软件附带的预配置模板库中选择警报。

虽然仪表板为您提供了应用程序及其状态的完整概述,但您也可以深入到代码级别并将AppOptics用作性能调谐器。这使得接收实时数据并立即在同一软件中进行故障排除变得很容易。

开发人员可以通过监视Java堆使用率、调用数、错误率和响应时间等指标来监视Java应用程序是否存在内存泄漏或其他许多问题。性能数据也可以通过日志、图表或瀑布跟踪历史地查看,这样可以很容易地缩小时间范围并隔离出问题代码行。

2. DataDog Java性能监控工具

datadog是专门为使监视Java应用程序成为一个简单而直观的过程而构建的。通过交互式仪表板,您可以在服务、客户和端点级别查看Java代码的状态。Datadog通过一个简单的软件即服务(SaaS)模型提供了这些见解。

一旦您输入了代码,DataDog就可以通过自动生成的服务映射识别Java问题、依赖关系和机会。所有这些数据都是从向DataDog报告信息的简单代理安装中提取的。主仪表板将实时和历史性能信息作为可视化和列表项引入,您可以对其进行排序。

总错误、延迟和请求数等指标可以通过仪表板轻松跟踪。可以将此视图更改为网络拓扑视图,以帮助更好地可视化查询之间的关系,以及性能如何影响链下游的其他功能。

通过警报仪表板,您可以根据正常运行时间、异常情况或您设置的特定阈值快速设置通知。很高兴看到这个软件允许您在设置警报模板时组合触发条件。通过尽可能细化您的警报条件,它有助于减少警报疲劳,并保持您的收件箱干净。警报可以通过电子邮件发送,也可以发送到Slack或Pagerduty等其他工具。

当您处理像Java应用程序的性能监视这样复杂的事情时,找到一个既直观又强大的工具会让您耳目一新。您可以免费测试DataDog及其所有功能14天。

3. VisualVM

VisualVM是一个Java故障排除工具,它直接连接到JDK来检测问题,并通过图形界面引起您的注意。开发人员可以查看他们的应用程序堆转储,分析他们的代码,并查看他们的Java应用程序的许多其他见解。因为它直接绑定到您的JDK中,所以可以方便地从您正在工作的地方访问它。

VisualVM相当轻量级,并且直接驻留在本地计算机上,这使得它非常适合在运行中进行故障排除,而且不必依赖基于SaaS的产品。虽然还有其他工具可以提供对Java相关问题的更深入的见解,但VisualVM是一个简单而干净的工具,它非常适合在故障排除过程的开始使用。

当谈到Java分析器时,VisualVM是一个很好的起点,但是您可能需要考虑将其与性能监视工具或其他更详细的探查器配对,以确保找到所有潜在的bug。

您可以在Windows、Linux或macOS操作系统上免费下载VisualVM

4. JPROFILER

JProfiler by EJ Technologies是一款Java评测器,它以易用性和与Java应用程序的轻松集成而自豪。在JVM级别,您可以在执行代码时查看并快速诊断代码中的问题。像Java代码中的内存泄漏这样的问题会在堆内存分析器下快速突出显示。打开和关闭的连接可以通过一个彩色编码的时间线可视化,这样就可以很容易地看到丢失的连接,这些连接保持打开状态并利用资源。JProfiler还有一个内置的堆遍历器,开发人员可以使用它从多个角度查看任何一组对象,以便进行更深入的检查。

默认情况下支持JEE,并将JEE组件分组到调用树中的组中,这样可以更容易地对更高级别的分析数据进行排序,下到粒度级别和其他子系统。

JProfiler与Windows、Linux和macOS兼容,可以使用试用密钥免费测试。

5. Eclipse内存分析器 MAT

为了获得堆内存的详细细分,Eclipse内存分析器被设计成突出显示内存收集中的缺陷并监视Java堆使用的健康状况。存储的任何对象都将显示并在堆中可见,Eclipse内存分析器将监视和报告内存的分配方式以及是否已清除。

仪表板精确地分解堆的大小,以及图表格式中哪些对象的大小最大。您可以配置自己的视图,也可以使用许多预先配置的视图按对象大小、重复类或顶级使用者进行排序。这些指标可以帮助您快速解决堆中的问题,并为优化性能设置更好的策略。

Eclipse内存分析器可以免费下载,并且与Windows、Linux和macOS系统兼容。

6. GLOWROOT

Glowroot是一个开源的java apm,设置起来很快,也很容易开始使用。只需将根目录文件解压并添加到你的浏览器面板上。

如果您需要一个开销极低的工具,Glowroot在资源消耗方面处于类的首位。大量的测试表明,Glowroot在其环境中造成的影响非常小,因此响应时间必须以微秒为单位进行记录。

除了运行极其精简的Glowroot之外,Glowroot还有许多其他特性,可以用来分析和监视Java应用程序。所有数据的实时和历史汇总可以通过MBean支持图表轻松执行实时和长期测试。虽然Glowroot并不是功能最丰富的性能监视器,但它确实提供了可配置的警报功能,从而为长期使用提供了额外的灵活性。

Glowroot可以免费下载,如果你想体验一下这个工具,它还附带了一个方便的演示站点。

https://glowroot.org/overhead.html

选择JAVA性能工具

Java内存泄漏可能会令人沮丧,但是确切地知道它是什么以及如何对其进行故障排除将使处理它们变得更加容易。我们知道Java内存泄漏是由于堆内存中的对象未清理而导致的。让我们回顾一下修复和防止内存泄漏的最佳方法。

使用Java编译器 - 你的工具包是一个很好的选择,这些工具将帮助您节省数不清的调试时间,并有助于突出显示代码中本来很难找到的问题。

使用可信的Java性能监视器 - Java性能监视器不仅可以提醒您代码中的问题,还可以帮助您在应用程序中发现内存泄漏的迹象,以免它影响到您的用户。

审核你的代码 - 在实现新代码时,定期的审核和测试可以起到很大的作用。安排审核以及清理Java将帮助您的应用程序运行更快,并使故障排除变得更容易。

以上就是Java 内存溢出的原因和解决方法的详细内容,更多关于Java 内存溢出的资料请关注其它相关文章!


推荐阅读
  • scrcpy通过adb调试的方式来将手机屏幕投到电脑上,并可以通过电脑控制您的Android设备。它可以通过USB连接,也可以通过Wifi连接(类似于隔空投屏),而且不需要任何ro ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • 2016 linux发行版排行_灵越7590 安装 linux (manjarognome)
    RT之前做了一次灵越7590黑苹果炒作业的文章,希望能够分享给更多不想折腾的人。kawauso:教你如何给灵越7590黑苹果抄作业​zhuanlan.z ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • Linux磁盘的分区、格式化的观察和操作步骤
    本文介绍了如何观察Linux磁盘的分区状态,使用lsblk命令列出系统上的所有磁盘列表,并解释了列表中各个字段的含义。同时,还介绍了使用parted命令列出磁盘的分区表类型和分区信息的方法。在进行磁盘分区操作时,根据分区表类型选择使用fdisk或gdisk命令,并提供了具体的分区步骤。通过本文,读者可以了解到Linux磁盘分区和格式化的基本知识和操作步骤。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • Linux下安装免费杀毒软件ClamAV及使用方法
    本文介绍了在Linux系统下安装免费杀毒软件ClamAV的方法,并提供了使用该软件更新病毒库和进行病毒扫描的指令参数。同时还提供了官方安装文档和下载地址。 ... [详细]
  • PL2303HXD电路图(USB转UART)介绍及应用
    本文介绍了PL2303HXD电路图(USB转UART)的特性和应用,该电路图可以实现RS232和USB信号的转换,方便嵌入到手持设备中。PL2303HXD作为USB/RS232双向转换器,可以将USB数据转换为RS232信息流格式发送给外设,并将RS232外设的数据转换为USB数据格式传送回主机。通过利用USB块传输模式和自动流量控制,PL2303HXD能够实现更高的数据传输吞吐量比传统的UART端口。 ... [详细]
  • java io换行符_Java IO:为什么从stdin读取时,换行符的数字表示出现在控制台上?...
    只是为了更好地理解我在讲座中听到的内容(关于Java输入和输出流),我自己做了这个小程序:publicstaticvoidmain(String[]args)thro ... [详细]
  • 本文摘自JavaGuide。1、简单易学;2、面向对象(封装,继承,多态);3、平台无关性(Java虚拟机实现平台无关性);4、可靠性;5、安全性;6、支持多线程(C++语言没有内 ... [详细]
author-avatar
CHEN--MIN--珊
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有