Java 性能优化实战记录(2)---句柄泄漏和监控

 

前言: Java不存在内存泄漏, 但存在过期引用以及资源泄漏. (个人看法, 请大牛指正) 

这边对文件句柄泄漏的场景进行下模拟, 并对此做下简单的分析.
如下代码为模拟一个服务进程, 忽略了句柄关闭, 造成不能继续正常服务的小场景.

复制代码
 1 public class FileHandleLeakExample {
 2 
 3     public static String readContentFromFile(String filename) {
 4         StringBuilder sb = new StringBuilder();
 5         BufferedReader br = null;
 6         try {
 7             br = new BufferedReader(new FileReader(filename));
 8             String line = null;
 9             while ( (line = br.readLine()) != null ) {
10                 sb.append(line).append("\n");
11             }
12         } catch (Exception e) {
13             System.err.println(e.getMessage());
14             exit(1);
15         } finally {
16 //          模拟疏忽关掉句柄的操作
17 //            try {
18 //                br.close();
19 //            } catch (IOException e) {
20 //                e.printStackTrace();
21 //            }
22         }
23         return sb.toString();
24     }
25 
26     public static void main(String[] args) {
27         while ( true ) {
28             FileHandleLeakExample.readContentFromFile("1.txt");
29         }
30     }
31 
32 }
33 
34 /*
35     输入结果如下:
36     1.txt (Too many open files)
37 */
复制代码

 

句柄泄漏导致, 进程服务达到系统设置的上限, 进而导致不可服务状态. 这就需要必要的监控了.

如何监控或者如何在测试阶段能提前发现呢?

在linux中, 一切皆句柄, 比如file, socket都是, 每个进程都有自己的上限, 一旦超过这个上限,系统就会限制并拒绝相应的资源请求.
这个设定如下所示:
ulimit -a             # ulimit -n 列出open file的个数

由此可见系统对于一般进程的文件句柄上限为 1024. 

但对上面那个java进程进行观察, 却发现如下不一致的地方,如下所示:

jps   #列出java进程的pid列表

cd /proc/<pid>/fd  #通过linux的虚拟文件系统,进入该java进程的系统信息 

ls | wc -l                #统计其总开打开的文件句柄数

其拥有的句柄个数4095与系统限制的句柄数上限1024相差太远, 这是什么情况?

实际上系统的限制, 分为两种,一种为soft limit, 另一种为hard limit, soft limit相当于一个warning, 而hard limit系统则不允许超越.

执行如下命令:

ulimit -a -H         # ulimit -n -H 列出open file的句柄数

现在系统的open file 4096的上限与java进程拥有的句柄数4095保持了一致.

关于soft limit和hard limit的区别, 请参阅如下链接:

http://blog.163.com/zhangjie_0303/blog/static/9908270620112233523316/

 

对于文件句柄数, 还可以借用lsof命令来查阅

lsof -p <pid>

 

 

 

posted on   mumuxinfei  阅读(3830)  评论(5编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示