专栏首页Java技术文章Java中堆的内存泄漏和内存溢出 及问题解决 参数设置
原创

Java中堆的内存泄漏和内存溢出 及问题解决 参数设置

首先内存泄漏问题、内存溢出问题可都能会OOM(OutofMemoryError)

堆空间不足

一、内存泄漏问题导致

1、内存泄漏:严格来说,只有对象不会再被程序用到了,但是GC又不能回收他们的情况,才叫内存泄漏,由于这些对象不能被垃圾收集掉,这样的对象多了,有可能就会OOM。

举一个生活中的不太恰当的例子:假设你有一个妹妹她小时候买了一个很可爱的玩偶,现在她长大了,但是这个玩偶还是一直都没有扔掉它,家里人也不会去丢掉它 ,那么这样的玩偶多了,一直在家就可能把你家堆满(OOM)。这个例子里的这个玩偶就相当于一个没有引用的对象,这个对象(玩偶)程序都不用了,但是由于它和其中某一个有引用的对象有联系,所以垃圾回收时也不会去回收它。

真实的举例:

(1)单例模式

单例的生命周期和应用程序是一样长的,所以单例程序中,如果持有对外部对象的引用的话,那么这个外部对象是不能被回收的,则会导致内存泄漏的产生。

(2)一些提供close的资源未关闭导致内存泄漏

数据库连接(dataSourse . getConnection()),网络连接(socket)和io连接必须手动close,否则是不能被回收的。

2、解决办法:如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots 的引用链。于是就能找到泄漏对象是通过的路径与GC Roots 相关链并导致垃圾收集器无法自动回收它们。掌握了泄漏对象的类型信息,以及GC Roots引用链的信息,就可以比较准确定位出泄漏代码的位置。

3、"GC Roots"根集合:一组必须活跃的引用。

基本思路:

➢可达性分析算法是以根对象集合(GC Roots) 为起始点,按照从上至下

➢使用可达性分析算法后,内存中的存活对象都会被根对象集合直接或间接连接着,搜索所走过的路径称为引用链

➢如果目标对象没有任何引用链相连,则是不可达的,就意味着该对象己经死亡,可以标记为垃圾对象

➢在可达性分析算法中,只有能够被根对象集合直接或者间接连接的对象才是存活对象

4、另外:MAT是Memory Analyzer的简称,它是一款功能强大的Java堆内存分析器。用于查找内存泄漏以及查看内存消耗情况。MAT是基于Eclipse开发的,是一款免费的性能分析工具。大家可以http://www.eclipse.org/mat/下载并使用MAT。MAT工具找GC Roots截图:

还推荐一款可视化工具 JProfiler,这也可以看到JVM内存动态信息。20版IDEA集成JProfiler工具(安装、集成、测试)教程

二、内存溢出问题导致

1、 如果不是内存泄漏,换句话说就是内存中的对象确实都是还必须存活着,栈中都还有引用。那就应当检查虚拟机的堆参数(-Xms和-Xmx),与机器物理内存对比看是否还可以调大堆内存大小,从代码上检查是否存在某些对象生命周期过长(静态修饰)、持有状态时间过长的情况,尝试减少程序运行期内存消耗。

2、内存溢出是没有空闲内存的情况:说明Java虛拟机的堆内存不够。原因有二:

(1) Java虛拟机的堆内存设置不够。

比如:可能存在内存泄漏问题;也很有可能就是堆的大小不合理,比如我们要处理比较可观的数据量,但是没有显式指定JVM堆大小或者指定数值偏小。我们可以通过参数-Xms、-Xmx来调整。

(2)代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)

3、初始堆空间默认大小是物理内存的1 / 64(-Xms),最大堆空间默认大小是物理内存1 / 4(-Xmx)。

调节堆内存大小的参数:-Xms600m -Xmx600m,中英文之间没有空格

参数表示含义:将堆空间的初始化内存大小设置为600兆,最大堆空间内存大小设置为600兆。

另外;通常情况我们都是将两者大小设置为一样,这这样就避免初始堆空间不足而去不断申请扩内存或者降低内存这个过程,因为这个过程会耗时,有一定的开销。

4、参数设置:

1)将Modules指定为JDK1.8(看你使用的是)

2)Java Complier 也设置为JDK1.8

3)进入Run添加参数设置,-Xms600m -Xmx60

另外:报OOM的原因不只是堆空间不足,还可能是方法区(元空间)不足导致,详细见这篇文章。

CSDN 我的原文地址:https://blog.csdn.net/qq_43012792/article/details/107407853

有用点个关注,手留余香!

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 基于JDK8的JVM内存模型详解与GC策略

    在JDK 8中,永久代被删除,类元数据在本机内存中分配。默认情况下,可用于类元数据的本机内存量是无限制的。使用该选项MaxMetaspaceSize可以为用于类...

    yingzi_code
  • 后浪,谈谈你对jvm性能调优的理解

    在我们日常的研发工作中, 经常会遇到系统的性能问题,这时我们必须进行系统的性能调优。系统调优分好多种,比如架构和代码优化、jvm调优、操作系统调优、数据库调优、...

    jinjunzhu
  • Java 自动内存管理机制及性能优化

    首先来看看Java虚拟机所管理的内存包括哪些区域,就像我们要了解一个房子,我们得先知道这个房子大体构造。根据《Java虚拟机规范(Java SE 7 版)》的规...

    我就是马云飞
  • 一次完整的JVM堆外内存泄漏故障排查记录

    记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些「JVM内存分配的原理分析」以及「常用的JVM问题排查手段和工具分享」,希望对大家有所帮助。

    Rude3Knife的公众号
  • 面试杂谈 - 内存泄漏如何排查

    Java的垃圾回收机制给了程序猿便利,我们可以不需要显式释放资源。但想高枕无忧却是不能,OOM像个隐藏在暗处的幽(hua)灵(nong),威胁着可怜、弱小又漂亮...

    Java_老男孩
  • 一次完整的JVM堆外内存泄漏故障排查记录

    记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些JVM内存分配机制以及常用的JVM问题排查指令和工具分享,希望对大家有所帮助。

    后端技术漫谈
  • JVM--对象创建

    虚拟机遇到一条new指令时,首先去检查这个指令的参数是否能在常量池中定位到一个符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,就必...

    SuperHeroes
  • Kubernetes Pod OOM 排查日记

    在一次系统上线后,我们发现某几个节点在长时间运行后会出现内存持续飙升的问题,导致的结果就是Kubernetes集群的这个节点会把所在的Pod进行驱逐OOM;如果...

    yoyofx
  • Android内存泄漏监控和优化技巧总结

    用户1263954
  • JS内存泄漏排查方法

    内存泄漏是一个累积的过程,只有页面生命周期略长的时候才算是个问题(所谓“刷新一下满血复活”)。频繁交互能够加快累积过程,偏展示的页面很难把这样的问题暴露出来。最...

    ayqy贾杰

扫码关注云+社区

领取腾讯云代金券