什么是资源泄漏

简单来说,就是程序打开文件、网络连接、数据库连接等资源后,使用完毕没有正确关闭。这些未被关闭的资源会一直占用系统资源,直到程序结束。在长时间运行的服务中,如果存在大量未关闭的IO流,最终会导致系统文件句柄耗尽,引发各种异常。

为什么必须手动关闭

Java的IO流底层都依赖操作系统的文件描述符。每个打开的文件、套接字都会占用一个描述符,而系统对单个进程能打开的文件数有限制。虽然垃圾回收机制会回收对象,但GC的时机不可控,而且垃圾回收器不会主动调用close()方法。如果依赖finalize()方法,它的执行时机不确定,完全无法保证及时释放资源。

典型问题场景

文件读取未关闭

异常处理不当

多层流嵌套时关闭不全

正确的关闭方式

传统的try-catch-finally

使用try-with-resources(JDK7+)

这种写法最推荐,无论是否发生异常,流都会自动关闭,代码也更简洁。

多层流的正确关闭

实际开发建议

代码审查时要特别注意IO关闭逻辑

使用Sonar等代码质量检测工具,它能识别出未关闭的资源

在高并发场景下,务必进行压力测试

养成“谁打开,谁关闭”的习惯

对于网络连接、数据库连接等,同样要注意及时关闭

排查工具

遇到“Too many open files”问题时,可以用以下命令排查:

lsof -p [pid] 查看进程打开的文件

ls -l /proc/[pid]/fd 查看文件描述符

记得有一次我们线上环境就因为一个文件上传功能没有关闭流,跑了三天就把整个服务拖垮了。后来加上了try-with-resources,问题彻底解决。这种问题虽然基础,但在实际开发中真的很常见,希望大家引以为戒。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐