什么是内存泄漏?

1.什么是内存泄漏?

​ 程序运行过程中会不断的分配内存空间,那些不再使用的内存空间应该即时被回收,从而保证系统可以再次使用这些内存,如果存在无用的内存没有被回收回来,那就是内存泄漏。

​ 对于我们java程序员来说,所有不可达的对象都由垃圾回收机制来负责回收,因此java程序员不需要考虑这部分的内存泄漏。但是如果程序中有一些java对象,它们处于可达状态,但是程序以后永远都不会再访问它们,那么它们所占用的内存空间也不会被回收,它们所占用的空间也会产生内存泄漏,对于java程序而言,只要它们一直处于可达状态,垃圾回收机制就不会回收它们,即使他们对于程序来说已经变成了垃圾(因为程序再也不需要它们了),而对于垃圾回收机制来说,它们还不是垃圾(因为对象还处于可达状态),因此不能进行回收。

​ 以下是一个存在内存泄漏问题的代码例子:

arduino 复制代码
public class StaticCollectionLeak {
	//static静态变量的生命周期:从类加载到JVM关闭,始终存在于内存中。
    private static final List<Object> LEAK_LIST = new ArrayList<>();
    
    public void addToList(byte[] obj){
        LEAK_LIST.add(obj);// obj对象被LEAK_LIST静态集合引用着,无法被回收
    }

    public static void main(String[] args) {
        StaticCollectionLeak leak = new StaticCollectionLeak();
        for (int i = 0; i < 1000000; i++){
            leak.addToList(new byte[1024*1024]);// 每次添加1MB对象
        }
        // LEAK_LIST未被清理,导致内存泄漏
    }
}

​ 解决方法1:在程序结束时清理静态集合(推荐简单场景)

typescript 复制代码
public class StaticCollectionLeak {
    private static final List<Object> LEAK_LIST = new ArrayList<>();

    public void addToList(Object obj) {
        LEAK_LIST.add(obj);
    }

    // 新增清理方法
    public static void clearList() {
        LEAK_LIST.clear();
    }

    public static void main(String[] args) {
        StaticCollectionLeak leak = new StaticCollectionLeak();
        try {
            for (int i = 0; i < 100; i++) {
                leak.addToList(new byte[1024 * 1024]);
            }
        } finally {
            // 确保在程序结束时清理
            clearList();
        }
    }
}

​ 解决方法2:改为非静态集合(推荐常规场景)

typescript 复制代码
public class SafeCollection {
    private final List<Object> tempList = new ArrayList<>();

    public void addToList(Object obj) {
        tempList.add(obj);
    }

    // 需要时手动清理
    public void clear() {
        tempList.clear();
    }

    public static void main(String[] args) {
        SafeCollection safe = new SafeCollection();
        for (int i = 0; i < 100; i++) {
            safe.addToList(new byte[1024 * 1024]);
            // 业务逻辑完成后清理
            if (i % 50 == 0) {
                safe.clear();
            }
        }
        // 对象销毁时自动GC回收
    }
}
相关推荐
飞快的蜗牛19 小时前
利用linux系统自带的cron 定时备份数据库,不需要写代码了
java·docker
聪明的笨猪猪19 小时前
Java Spring “IOC + DI”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
ThisIsMirror20 小时前
CompletableFuture并行任务超时处理模板
java·windows·python
珹洺20 小时前
Java-Spring入门指南(二十一)Thymeleaf 视图解析器
java·开发语言·spring
源码集结号20 小时前
一套智慧工地云平台源码,支持监管端、项目管理端,Java+Spring Cloud +UniApp +MySql技术开发
java·mysql·spring cloud·uni-app·源码·智慧工地·成品系统
EnCi Zheng21 小时前
Spring Security 最简配置完全指南-从入门到精通前后端分离安全配置
java·安全·spring
程序员小假21 小时前
为什么这些 SQL 语句逻辑相同,性能却差异巨大?
java·后端
泉城老铁21 小时前
springboot实现对接poi 导出excel折线图
java·spring boot·后端
金銀銅鐵21 小时前
[Java] 如何自动生成简单的 Mermaid 类图
java·后端
纵横八荒1 天前
Java基础加强13-集合框架、Stream流
java·开发语言