java堆空间和消息丢失

eqzww0vc  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(284)

我在许多相互作用的计算机上运行一个java程序。几个小时(2-5个小时)后,计算机开始出现故障(线程开始进入死锁,消息开始丢失——如果你考虑到在最初的一个小时左右,事情运行得很好,那就奇怪了)。
我怀疑是因为我用了太多的内存。我在linux上运行,所以这是 top :

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
30376 username  18   0  976m 132m 6804 S    0  4.0   0:05.60 java

这看起来高吗?
其他关于为什么会发生这些错误的想法将受到欢迎。。

uemypmqf

uemypmqf1#

可能的问题:
资源(套接字、数据库等)未正确关闭
内存泄漏(引用保存在集合中,非关闭的资源)
很少出现的微妙的并发错误(在几个小时后就会出现)
套接字上缓冲区的消息丢失在您有机会读取它或获取比缓冲区大的消息之前被覆盖,通常通过让线程读取套接字来纠正,只要数据进入套接字并将其放入主处理线程可以处理的工作队列中

zi8p0yeb

zi8p0yeb2#

另一件可能发生的事情是,你正在运行的连接。就在昨天,我的一个同事发生了这种事。 ulimit -n 将告诉您可以打开多少个文件句柄; netstat -at 会告诉你有多少插座是开着的。当第二个数字接近第一个数字时,打开连接的尝试将开始失败。
在这种特殊情况下,当连接仍处于 OPEN_WAIT 使用后,强制垃圾收集( Runtime.gc() )有帮助。

wn9m85ua

wn9m85ua3#

通过查看jvm堆化的状态并定期记录它,您可以了解内存使用的趋势。从这些日志中,你可以绘制一个图表,看看是否有异常(顺便说一句,拼图模式是正常的垃圾收集行为。)

// Memory status
    Runtime     runtime =   Runtime.getRuntime();
    final long  totalMem =  runtime.totalMemory();
    final long  freeMem =   runtime.freeMemory();
    if (log.isDebugEnabled()) {
        log.debug("Memory free=" + freeMem + 
                " used=" + (totalMem - freeMem) + 
                " total=" + totalMem);
    }

相关问题