将对象放入 静态 或 生命周期很长 的集合(如 public static List<Object> list = new ArrayList<>();),即使后面不再需要,集合仍持有其引用,导致无法GC

2、未关闭的资源

连接、流等资源未调用 close() 方法关闭。这些资源不仅占用内存,还可能占用文件句柄(操作系统分配的唯一标识,凭它,你才能操作文件资源)、网络连接等系统资源。比如 数据库连接、文件流(FileInputStream)、Socket连接 等。

public class FileTest {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("test.txt");
            // 读取文件,未调用 fis.close()
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 未调用 fis.close() → fis 持有 Native 引用,无法回收
        }
    }
}

3、ThreadLocal 使用不当

将对象存入 ThreadLocal 后,未在后续调用 remove() 清理。若线程来自线程池(会复用),其 ThreadLocalMap 中的值会一直存活。

public class ThreadLocalTest {
    private static ThreadLocal<User> userThreadLocal = new ThreadLocal<>();

    public static void main(String[] args) {
        // 线程池(核心线程长期存活)
        TThreadPoolExecutor executor = new ThreadPoolExecutor(
                2,
                4,
                10,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(100),
                new ThreadFactoryBuilder().setNameFormat("my-thread-pool-%d").setDaemon(false).setPriority(Thread.NORM_PRIORITY).build(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        executor.submit(() -> {
            User user = new User("李四", 30);
            userThreadLocal.set(user); // 存储到 ThreadLocal

            // 业务执行完毕,未调用 remove()
            // 核心线程不会销毁,ThreadLocal 仍持有 user 引用
        });
    }
}

ps:未进行 remove(),还可能会导致 ThreadLocal 取值串门。

4、内部类与外部类引用

非静态内部类(或匿名类)会 隐式持有 外部类的引用。如果内部类实例生命周期更长(如被缓存或另一个线程引用),会阻止外部类被回收。

public class OuterClass {
    private byte[] bigData = new byte[1024 * 1024 * 10]; // 10MB 大对象

    // 非静态内部类
    class InnerClass {
        // 内部类隐式持有 OuterClass 引用
    }

    public InnerClass createInner() {
        return new InnerClass();
    }

    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        InnerClass inner = outer.createInner();

        // 置空外部类引用,但 inner 仍持有 outer 引用
        outer = null;

        // 若 inner 被静态变量/线程长期持有 → outer 对象(含 bigData)无法回收
    }
}

5、 监听器与回调

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐