开发易忽视的问题:内存溢出/泄漏案例

内存溢出和内存泄漏区别

对比项 内存溢出(OOM) 内存泄漏(Memory Leak)
定义 程序请求的内存超出了 JVM 可用内存 不再使用的对象仍然被引用,导致 GC 无法回收
本质 申请的内存超限,无法再分配 对象的生命周期比预期更长,导致无用对象占用内存
影响 直接导致程序崩溃 程序运行变慢,可能最终导致 OOM
原因 过多对象创建、JVM 配置不足、无限递归等 没有释放资源(如静态集合、线程、Socket、数据库连接等)
修复方法 优化代码、增加 JVM 堆大小、减少无用对象 及时释放资源、使用弱引用(WeakReference)、优化对象管理

溢出案例

现象 :不断向 堆(Heap) 中分配内存,导致 java.lang.OutOfMemoryError: Java heap space

案例

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class HeapOOM {
    static class OOMObject {}

    public static void main(String[] args) {
        List<OOMObject> list = new ArrayList<>();
        while (true) {
            list.add(new OOMObject()); // 不断向 list 添加对象,导致堆溢出
        }
    }
}

原因

  • 不断创建新对象,导致 堆内存被占满,GC 也无法回收。

解决方案

  • 代码优化,避免对象长时间引用
  • 使用 WeakReference 进行缓存管理

泄漏案例

java 复制代码
// Leak example
import java.util.HashMap;
import java.util.Map;

public class HashMapLeakDemo {
    public static class Key {
        String title;

        public Key(String title) {
            this.title = title;
        }
    }

    public static void main(String[] args) {
        Map<Key, Integer> map = new HashMap<>();
        map.put(new Key("1"), 1);
        map.put(new Key("2"), 2);
        map.put(new Key("3"), 2);

        Integer integer = map.get(new Key("2"));
        System.out.println(integer);
    }
}

📌 问题分析

  1. Key 类没有 重写 equals()hashCode() 方法
  2. HashMap 依赖 hashCode() 计算存储位置new Key("2") 生成的是新对象,默认 hashCode() 不是同一个,导致 get(new Key("2")) 返回 null
  3. 解决方案 :重写 equals()hashCode() 方法,保证 Key 对象逻辑相等时哈希值一致。

💡 修正代码

java 复制代码
public static class Key {
    String title;

    public Key(String title) {
        this.title = title;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Key key = (Key) obj;
        return title.equals(key.title);
    }

    @Override
    public int hashCode() {
        return title.hashCode();
    }
}

🔹 这样 map.get(new Key("2")) 就能正确返回 2 了! 🚀

即使提供了 equals 方法和 hashCode 方法,也要非常小心,尽量避免使用自定义的对象作为 Key。

相关推荐
ictI CABL5 分钟前
SpringBoot3.3.0集成Knife4j4.5.0实战
java
Ruci ALYS6 分钟前
SpringBoot Maven快速上手
spring boot·后端·maven
java1234_小锋9 分钟前
谈谈Ribbon和Feign区别?
后端·spring cloud·ribbon
傻瓜搬砖人10 分钟前
SpringMVC的请求
java·前端·javascript·spring
亚历克斯神10 分钟前
Java 开发者 2026 成长路线图:从初级到架构师
java·spring·微服务
佛系彭哥12 分钟前
用飞算JavaAI做项目:在线图书借阅平台设计与实现
java·飞算javaai炫技赛
亚历克斯神14 分钟前
Java 代码质量保障:静态分析与代码审查实践
java·spring·微服务
一叶飘零_sweeeet16 分钟前
2026 年 Java 面试必问:Spring AI 核心原理,90% 人答不全
java·面试·spring ai
星河耀银海16 分钟前
JAVA 泛型与通配符:从原理到实战应用
android·java·服务器
咱那飘逸的长发19 分钟前
Trae java项目配置全局maven和jdk
java·python·maven