我有一个Java程序,运行大约3分钟后会抛出"打开太多文件"错误.增加打开文件限制不起作用,因为它仍然用尽所有限制,只是更慢.所以我的程序有问题,我需要找出答案.
这就是我所做的,10970
是pid
cat /proc/10970/fd
找出大多数是管道lsof -p 10970 | grep FIFO
列出所有管道,找到约450管java 10970服务1w FIFO 0,8 0t0 5890管道
java 10970服务2w FIFO 0,8 0t0 5890管道
java 10970服务169r FIFO 0,8 0t0 2450696管道
java 10970服务201r FIFO 0,8 0t0 2450708管道
但我不知道如何继续.0,8
在上面的输出中表示设备编号.如何找到带有这些数字的设备?
更新
该程序是TCP服务器,从客户端和处理消息接收套接字连接.我有两个环境.在生产环境中它工作正常,但在测试环境中它最近有这个问题.在生产环境中,我没有看到这么多管道.这两个环境的代码和基础结构是相同的,都由Chef管理.
我们的 Java 应用程序在后端使用Google Guava EventBus进行通信。其中一些事件使用 Jersey 的服务器发送事件 支持发送到客户端以启用通知。客户端仅对某些类型的事件感兴趣,并且这些事件以 JSON 格式发送到客户端。
目前,我们正在使用if-else
withinstanceof
来处理巨型方法中的 JSON 正文生成。UIEvent
只是一个用作过滤器的标记接口。
@Subscribe
public void handleEvent(final UIEvent event) {
if (event instanceof A) {
A a = (A) event;
} else if (event instance B) {
B b = (B) event;
} ...
}
Run Code Online (Sandbox Code Playgroud)
当越来越多的事件添加到系统中时,这段代码开始变得混乱。经过一番研究,有一些替代方案,但还不够好。
1)反思。
使用反射意味着我们可以使用声明性方式从事件对象中检索数据,而无需知道确切的类型。但是使用反射不是类型安全的,并且在处理嵌套路径时可能会很混乱,例如a.b.c
.
2)多态性
多态性看起来是一个很好的替代方案instanceof
,但在这种情况下确实有效。使用多态性意味着toJSON
向UIEvent
接口添加类似的方法。但这会恢复依赖流并将 UI 详细信息暴露给事件总线。
3)包装类
我还在考虑使用事件包装器类将 JSON 主体构建逻辑封装在单独的类中。然后在事件总线的handleEvent
方法中,我可以获取事件对象的类型并使用命名约定找到包装类,然后构造包装类实例,调用toJson
方法来获取 JSON 主体。 …