java - 对无限制的 Java 驻留集大小 (RSS) 增长进行故障排除

标签 java memory

我有一个独立的 Java 应用程序,它具有:

-Xmx1024m -Xms1024m -XX:MaxPermSize=256m -XX:PermSize=256m

随着时间的推移,它占用越来越多的内存,开始交换(并减慢速度)并最终死了很多次(不是 OOM+dump,只是死了,/var/log/messages 上没有任何内容)。

到目前为止我已经尝试过:

  1. 堆转储: Activity 对象从 1G 堆中取出 200-300Mb --> 可以使用堆
  2. Activity 线程的数量相当恒定(~60-70)-->线程堆栈没问题
  3. JMX 在某个时刻停止应答(mb 它应答,但超时时间较短)
  4. 关闭交换 - 它死得更快
  5. strace - 似乎一切都变慢了一点,应用程序仍然没有死,并且不确定在那里查找哪些内容
  6. 检查顶部:VIRT 增长到 5.5Gb,RSS 增长到 3.7Gb
  7. 检查 vmstat(显然我们开始交换):

     --------------------------procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
    Sun Jul 22 16:10:26 2012:  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
    Sun Jul 22 16:48:41 2012:  0  0 138652 2502504  40360 706592    1    0   169    21 1047  206 20  1 74  4  0
    . . . 
    Sun Jul 22 18:10:59 2012:  0  0 138648  24816  58600 1609212    0    0   124   669  913 24436 43 22 34  2  0
    Sun Jul 22 19:10:22 2012: 33  1 138644  33304   4960 1107480    0    0   100   536  810 19536 44 22 23 10  0
    Sun Jul 22 20:10:28 2012: 54  1 213916  26928   2864 578832    3  360   100   710  639 12702 43 16 30 11  0
    Sun Jul 22 21:10:43 2012:  0  0 629256  26116   2992 467808   84  176   278  1320 1293 24243 50 19 29  3  0
    Sun Jul 22 22:10:55 2012:  4  0 772168  29136   1240 165900  203   94   435  1188 1278 21851 48 16 33  2  0
    Sun Jul 22 23:10:57 2012:  0  1 2429536  26280   1880 169816 6875 6471  7081  6878 2146 8447 18 37  1 45  0
    
  8. sar 还显示稳定的系统百分比增长 = 交换:

     15:40:02          CPU     %user     %nice   %system   %iowait    %steal     %idle
     17:40:01          all     51.00      0.00      7.81      3.04      0.00     38.15
     19:40:01          all     48.43      0.00     18.89      2.07      0.00     30.60
     20:40:01          all     43.93      0.00     15.84      5.54      0.00     34.70
     21:40:01          all     46.14      0.00     15.44      6.57      0.00     31.85
     22:40:01          all     44.25      0.00     20.94      5.43      0.00     29.39
     23:40:01          all     18.24      0.00     52.13     21.17      0.00      8.46
     12:40:02          all     22.03      0.00     41.70     15.46      0.00     20.81
    
  9. 检查 pmap 可以得出以下最大的贡献者:

      000000005416c000 1505760K rwx--    [ anon ]
      00000000b0000000 1310720K rwx--    [ anon ]
      00002aaab9001000 2079748K rwx--    [ anon ]
    
  10. 尝试将我从 pmap 获得的地址与 strace 转储的内容关联起来,但没有找到匹配项

  11. 添加更多内存并不实际(只会让问题稍后出现)

  12. 无法切换 JVM(env 不在我们的控制之下)

问题是: 我还可以尝试什么来找出问题的原因或尝试解决它?

最佳答案

JVM 中的某些内容正在使用“无限”量的非堆内存。一些可能的候选者是:

  • 线程堆栈。
  • 由某些 native 代码库分配的 native 堆。
  • 内存映射文件。

当您进行线程堆栈转储时,第一种可能性将显示为大量(且不断增加)的线程。 (检查一下...好吗?)

如果您的应用程序(或其使用的某些第三部分库)不使用任何 native 库,您(可能)可以消除第二个。

如果您的应用程序(或其使用的某些第三部分库)不使用内存映射文件,则可以消除第三个。


我猜你没有看到 OOME 的原因是你的 JVM 被 Linux OOM killer 杀死了。 JVM 也有可能在 native 代码中退出(例如,由于未正确处理 malloc 失败),但我认为 JVM 崩溃转储将是更可能的结果......

关于java - 对无限制的 Java 驻留集大小 (RSS) 增长进行故障排除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11606839/

相关文章:

不使用 sprintf() 将 float 转换为字符串

java - 当我们使用赋值而不是比较时,如何评估 if/while 条件?

java.nio.file.path : inconsistent behaviour with name count?

java - 在Maven项目中导入Cplex库时如何修复 'IncompatibleClassChangeError: Implementing Class'?

c - 为什么即使在 C 中的 "clearing"之后我的数组仍然包含垃圾值

c++ - abi::__cxa_demangle 无法重用其自身返回的内存

java - Hibernate 查询以 SQL 语法错误结束

java - 阻止工具提示在 JFreeChart 中消失的最佳方法

c++ - 立即作为参数传递的对象的生命周期是多少?

tomcat - 一个Tomcat线程占用多少内存?