Java内存之谜(我是否有泄漏)?

25 浏览
0 Comments

Java内存之谜(我是否有泄漏)?

我在Linux服务器上运行一个独立的Java问题。我使用-Xmx256m启动了JVM。我附加了一个JMX监视器,并且可以看到堆从未真正超过256Mb。但是,在我的Linux系统上运行top命令时,我可以看到:

1)首先,该进程的RES内存使用量约为350Mb。为什么?我想这是因为堆之外的内存吗?

2)其次,该进程的VIRT内存使用量不断增长。它永远不停止!它现在显示为2500Mb!那么我是否有泄漏?但是堆不增加,只是循环!

最终,这会带来问题,因为系统的交换会不断增长,最终导致系统死机。

有什么想法是怎么回事吗?


我想要问的重要问题是,这可能是我的代码而不是JVM、内核等导致的结果的一些情况。例如,如果线程数量不断增长,是否符合我观察到的描述?您能否建议我注意类似的任何情况?

admin 更改状态以发布 2023年5月22日
0
0 Comments

测试交换Sun与IBM JVM


  1. RES将包括代码+非堆数据。此外,一些您认为应该存储在堆中的东西实际上不是,例如线程堆栈和“类数据”。 (这是一个定义问题,但代码和类数据由 -XX:MaxPermSize = 控制。)

  2. 这听起来像是JVM实现、Linux内核或库JNI代码中的内存泄漏。

如果使用Sun JVM,请尝试IBM JVM,反之亦然。

我不确定dlopen的工作原理,但是如果可能的话,访问系统库的代码可能会重复重新映射同一个东西。

最后,您应该使用ulimit来使系统更早地失败,这样您可以轻松重复测试。

0
0 Comments

可能存在几个问题:

  • 直接分配的缓冲区和内存映射文件在Java堆之外分配,并且不能方便地处理。
  • 为每个新线程保留一定的堆栈区域。
  • 永久代(代码和字符串池)在通常的堆栈之外。如果类加载器泄漏(通常在重新加载Web应用程序时),它可能会成为问题。
  • 有可能C堆泄漏。

pmap -x 应该显示您的内存是如何消失的。

0