iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >一篇文章带你搞定JAVA内存泄漏
  • 719
分享到

一篇文章带你搞定JAVA内存泄漏

2024-04-02 19:04:59 719人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录1、什么是内存泄漏2、内存泄漏的原因3、内存泄漏有哪些情况3.1 代码中没有及时释放,导致内存无法回收。3.2 资源未关闭造成的内存泄漏3.3 全局缓存持有的对象不使用的时候没有

1、什么是内存泄漏

内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏。随着垃圾回收器活动的增加以及内存占用的不断增加,程序性能会逐渐表现出来下降,极端情况下,会引发OutOfMemoryError导致程序崩溃。

2、内存泄漏的原因

JVM 虚拟机是使用引用计数法和可达性分析来判断对象是否可回收,本质是判断一个对象是否还被引用,如果没有引用则回收。在开发的过程中,由于代码的实现不同就会出现很多种内存泄漏问题,让gc 系统误以为此对象还在引用中,无法回收,造成内存泄漏。

3、内存泄漏有哪些情况

3.1 代码中没有及时释放,导致内存无法回收。

下面的代码,因为是双向链表,但是断开的不够彻底,prev节点依然引用这当前正在使用的节点,导致无法回收


public class Listnode {
    int val;
    ListNode next;
    ListNode prev;
    ListNode() {
    }
    ListNode(int val) {
        this.val = val;
    }
    public ListNode(int val, ListNode next, ListNode prev) {
        this.val = val;
        this.next = next;
        this.prev = prev;
    }

    public static void main(String[] args) {
        ListNode curr = new ListNode(1);
        ListNode prev = new ListNode(2);
        ListNode next = new ListNode(3);
        curr.prev = prev;
        curr.next = next;
        curr.prev = null;
    }
}

    public static void main(String[] args) {
        ListNode curr = new ListNode(1);
        ListNode prev = new ListNode(2);
        ListNode next = new ListNode(3);
        curr.prev = prev;
        curr.next = next;
        curr.prev = null;
    }
}

3.2 资源未关闭造成的内存泄漏

各种连接,如数据库连接、网络连接和io连接等,文件读写等,可以使用 try-with-resources 读取完文件,自动资源释放


try (RandoMaccessFile raf = new RandomAccessFile(filePath, "r");) {
        Image image = null;
while((image = parseImage(raf)) != null){
            imageList.add(image);
        }
        return imageList;
} catch(Exception e){
    log.error("parse file error, path: {},", path, e);
    return null;
}

3.3 全局缓存持有的对象不使用的时候没有及时移除,导致一直在内存中无法移除

3.4 静态集合

HashMap、LinkedList等等。如果这些容器为静态的,那么它们的生命周期与程序一致,则容器中的对象在程序结束之前将不能被释放,从而造成内存泄漏。生命周期长的对象持有短生命周期对象的引用,尽管短生命周期的对象不再使用,但是因为长生命周期对象持有它的引用而导致不能被回收。

3.5 堆外内存无法回收

堆外内存不受gc的管理,可能因为第三方的bug出现内存泄漏

4、内存泄漏的解决办法

1.尽量减少使用静态变量,或者使用完及时 赋值为 null。

2.明确内存对象的有效作用域,尽量缩小对象的作用域,能用局部变量处理的不用成员变量,因为局部变量弹栈会自动回收;

3.减少长生命周期的对象持有短生命周期的引用;

4.使用StringBuilder和StringBuffer进行字符串连接,Sting和StringBuilder以及StringBuffer等都可以代表字符串,其中String字符串代表的是不可变的字符串,后两者表示可变的字符串。如果使用多个String对象进行字符串连接运算,在运行时可能产生大量临时字符串,这些字符串会保存在内存中从而导致程序性能下降。

5.对于不需要使用的对象手动设置null值,不管GC何时会开始清理,我们都应及时的将无用的对象标记为可被清理的对象;

6.各种连接(数据库连接,网络连接,IO连接)操作,务必显示调用close关闭。

5、内存问题排查

没有任何一个程序员想要出现这种问题,但是出现了问题也要解决,内存泄漏的主要表象就是内存不足,内存告警之后如何判断是否有内存泄漏。

第一步 首先确认逻辑问题

查看内存中对象的数量和大小,判断是否在合理的范围,如果在合理的范围内,增大内存配置,调整内存比例就可以了。

命令:

jmap -heap pid

图片

第二步:分析gc是否正常执行

命令:

jstat -gcutil <pid> 1000

图片


S0 — Heap上的 Survivor space 0 区已使用空间的百分比    
S1 — Heap上的 Survivor space 1 区已使用空间的百分比    
E — Heap上的 Eden space 区已使用空间的百分比    
O   — Heap上的 Old space 区已使用空间的百分比    
P   — Perm space 区已使用空间的百分比
YGC — 从应用程序启动到采样时发生 Young GC 的次数
YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒)    
FGC — 从应用程序启动到采样时发生 Full GC 的次数
FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒)    
GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)
LGCC - 进行GC的原因(低版本jdk可能没有这一列)

从这里观察gc是否异常,也可以根据这个进行jvm内存分配调优,来提高性能降低gc对性能的损耗

第三步 确认下版本新增代码的改动,尽快从代码上找出问题。

第四步:开启各种命令行和 导出 dump 各种工具分析


-XX:+HeapDumpOnOutOfMemoryError
-XX:OnError
-XX:+ShowMessageBoxOnError

推荐使用jprofile 进行本地分析,可以不用记住那么多命令。

图片

总结:

现在的服务器内存虽然很大,但是且用且珍惜,不要等到出现问题了才知道后果,在开发中规范自己代码,用完的对象及时释放,减少垃圾对象。出现问题了也不要慌,仔细分析代码,一切都是有原因的。

本篇文章就到这里了,希望能给你带来帮助,也希望您能多多关注编程网的更多内容!

--结束END--

本文标题: 一篇文章带你搞定JAVA内存泄漏

本文链接: https://www.lsjlt.com/news/130455.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 一篇文章带你搞定JAVA内存泄漏
    目录1、什么是内存泄漏2、内存泄漏的原因3、内存泄漏有哪些情况3.1 代码中没有及时释放,导致内存无法回收。3.2 资源未关闭造成的内存泄漏3.3 全局缓存持有的对象不使用的时候没有...
    99+
    2022-11-12
  • 一篇文章带你搞定JAVA Maven
    目录1、maven是什么,为什么存在?项目结构是什么样子,怎么定位jar2、Idea 的操作1.新建maven项目2.配置仓库3.添加依赖,添加fastjson的依赖4.打包项目3、...
    99+
    2022-11-12
  • 一篇文章带你搞定JAVA泛型
    目录1、泛型的概念2、泛型的使用3、泛型原理,泛型擦除3.1 IDEA 查看字节码3.2 泛型擦除原理4、?和 T 的区别5、super extends6、注意点1、静态方法无法访问...
    99+
    2022-11-12
  • 一篇文章带你搞定JAVA注解
    目录1、注解是什么2、jdk支持的注解有哪些2.1 三种常用的注解:2.2 元注解3、注解实例1、自定义注解2、在对应的方法上增加注解3、在项目启动的时候检查注解的枚举4、总结1、注...
    99+
    2022-11-12
  • 一篇文章带你搞定JAVA反射
    目录1、反射的概念1、概念2、获取字节码文件对象的方式2.1 元数据的概念2.2 获取class对象的方式1、访问权限2、获取方法2.1 访问静态方法2.2 访问类方法 3...
    99+
    2022-11-12
  • 一篇文章弄懂javascript内存泄漏
    1、什么是内存泄漏 在了解什么是内存泄漏之前, 我们应该要对内存是什么有个概念, 随机存取存储器(英语:Random Access Memory,缩写:RAM)是与 CPU 直接交...
    99+
    2022-11-12
  • 一篇文章教你如何排查.NET内存泄漏
    目录前言检查托管内存使用 生成dump文件 分析 core dump 总结前言 内存泄漏通常表示:一个应用程序的某些对象在完成它的的生命周期后,由于它被其他对象意外引用,导致后续gc...
    99+
    2022-11-12
  • 一篇文章带你搞定Python多进程
    目录1.Python多进程模块2.Python多进程实现方法一3.Python多进程实现方法二4.Python多线程的通信5.进程池1.Python多进程模块 Python中的多进程...
    99+
    2022-11-12
  • 一篇文章带你搞懂Java restful 接口开发
    目录1、RESTful 简介a>资源b>资源的表述c>状态转移2、RESTful 的实现3、HiddenHttpMethodFilter4、RESTful 案例4....
    99+
    2022-11-12
  • 轻松搞定Java内存泄漏(转)
    轻松搞定Java内存泄漏(转)[@more@] 抽象  尽管java虚拟机和垃圾回收机制管理着大部分的内存事务,但是在java软件中还是可能存在内存泄漏的情况。的确,在大型工程中,内存泄漏是一个普遍问题。避免内存泄漏的第一步,就是要了解他们...
    99+
    2023-06-03
  • 一篇文章带你了解JVM内存模型
    目录1. JVM介绍 1.1 什么是JVM?1.2 JVM的优点 1.2.1 一次编写,到处运行。1.2.2 自动内存管理,垃圾回收机制。1.2.3 数组下标越界...
    99+
    2022-11-12
  • 一篇文章带你彻底搞懂Redis 事务
    目录Redis 事务简介Redis 事务基本指令实例分析Redis 事务与 ACID总结Redis 事务简介 Redis 只是提供了简单的事务功能。其本质是一组命令的集合,事务支持一...
    99+
    2022-11-13
    redis有几种部署方式 redis事务三大特性 redis怎么做到事务回滚
  • 一篇文章带你彻底搞懂Redis 事务
    目录Redis 事务简介Redis 事务基本指令实例分析Redis 事务与 ACID总结Redis 事务简介 Redis 只是提供了简单的事务功能。其本质是一组命令的集合,事务支持一次执行多个命令,在事务执行过程中,会顺...
    99+
    2022-10-31
  • 一篇文章带你搞懂VUE基础知识
    目录VUE是什么Vue中的核心插件  VueRouterVuexaxioselement-uiVue前端整体架构 总结VUE是什么 Vue (读音 /v...
    99+
    2022-11-12
  • 一篇文章带你搞懂Java线程池实现原理
    目录1. 为什么要使用线程池2. 线程池的使用3. 线程池核心参数4. 线程池工作原理5. 线程池源码剖析5.1 线程池的属性5.2 线程池状态5.3 execute源码5.4 wo...
    99+
    2022-11-13
    Java线程池实现原理 Java线程池原理 Java线程池实现 Java线程池
  • 一篇文章带你入门Java Script
    目录概述特点和Java的区别弱类型语言强类型语言书写位置数组函数JS中的自定义对象(扩展内容)Object形式的自定义对象JS中的事件常用的事件:动态注册基本步骤:DOM模型总结概述...
    99+
    2022-11-12
  • 一篇文章带你了解C语言内存对齐
    目录内存对齐三、在内存对齐话题下的sizeof与offsetof宏3.1、sizeof3.2、offsetof宏3.3、Debug总结内存对齐 先看如下代码: 结构体Test1...
    99+
    2022-11-12
  • 一篇文章带你轻松搞懂Golang的error处理
    目录Golang中的errorerror的几种玩法哨兵错误自定义错误类型Wrap errorGolang1.13版本error的新特性errors.UnWrap()errors.Is...
    99+
    2022-11-13
  • 一篇文章带你搞懂Python类的相关知识
    目录一、什么是类二、类的方法三、类的特性四、总结一、什么是类 类(class),作为代码的父亲,可以说它包裹了很多有趣的函数和方法以及变量,下面我们试着简单创建一个吧。 这样就算创...
    99+
    2022-11-12
  • 一篇文章带你搞懂Go语言标准库Time
    目录前言时间类型时间戳时间间隔操作时间AddSubEqualBeforeAfter定时器时间格式化解析字符串格式的时间总结前言 在编程过程中,我们经常会用到与时间和日期相关的各种需求...
    99+
    2022-11-11
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作