Java进程内存远大于指定的限制 [英] Java process memory is much bigger than specified limits

查看:1913
本文介绍了Java进程内存远大于指定的限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经研究了大多数可用的方法,以找出java进程实际使用的内存量。
到目前为止,我可以说我知道分配的总内存可能是以下一项或多项:

I've researched through most of the methods available to find out how much memory a java process is really using, at all. So far, I can say I know the total memory allocated could be one or more of the following:


  • 堆内存(据说由我的-XX控制:MaxHeapSize = 4096m)

  • 永久内存(据说由我-XX控制:MaxPermSize = 1024m)

  • 保留代码缓存(据说由我的-XX控制:ReservedCodeCacheSize = 256m)

  • 线程数N *线程大小(据说由我的-XX控制:ThreadStackSize = 1024)

  • Heap Memory (supposedly controlled by my -XX:MaxHeapSize=4096m)
  • Permanent Memory (supposedly controlled by my -XX:MaxPermSize=1024m)
  • Reserved Code Cache (supposedly controlled by my -XX:ReservedCodeCacheSize=256m)
  • N of Threads * Thread Size (supposedly controlled by my -XX:ThreadStackSize=1024)

但结果与linux告诉我的结果太不一样了,我发现任何可用于获取java进程内存消耗的方法。

But the results are too different from what linux tells me, with any of the methods I found available to get memory consumption of a java process.

在我的例子中,它是在Ubuntu 11.10 x86_64机器上运行的Tomcat实例,JVM 1.6_u26 64位,以及 ps -ALcf | grep org.apache.catalina.startup.Bootstrap | wc -l <​​/ code>告诉我有145个线程或进程在运行,链接到同一个根进程(Tomcat)。

In my case it is a Tomcat instance running on a Ubuntu 11.10 x86_64 machine, JVM 1.6_u26 64-bit, and ps -ALcf | grep org.apache.catalina.startup.Bootstrap | wc -l tells me I have 145 threads or processes running, linked all to the same root process (Tomcat).

这些都归结为应该给我总的最大内存
(4096MB)+(1024MB)+(256MB)+ 145 *(1024KB)= 5521MB。
什么 jmap -heap PID 告诉我, ManagementFactory.memoryMXBean。(heapMemoryUsage + nonHeapMemoryUsage).getCommitted()告诉我,上面的理论值都是对。

That all summed up should give me total max memory of (4096MB) + (1024MB) + (256MB) + 145 * (1024KB) = 5521MB. What jmap -heap PID tells me, what ManagementFactory.memoryMXBean.(heapMemoryUsage + nonHeapMemoryUsage).getCommitted() tells me, and the theoric value above are all on pair.

现在到linux方面, top nmon 都告诉我这个过程分配的ResidentMemory是5.8GB - >大约5939,2MB。但我也知道这只是内存的一部分,是RAM内存的一部分。 VIRT by top 和Size by nmon (两者都应该代表相同)告诉我这个过程是7530MB(或正好是7710952KB nmon )。
这与预期的最大值不同: 2009MB高于最大值,根据jmap和jstat,堆内存分配甚至没有达到峰值(2048-OldSpace + 1534-Eden_ + _Survivors)。

Now to the linux side, top and nmon both tells me ResidentMemory allocated by this process is 5.8GB -> roughly 5939,2MB. But I also know this is only part of the memory, the part in live RAM memory. VIRT by top and Size by nmon (both are supposed to represent the same) tells me the process is 7530MB (or precisely 7710952KB by nmon). This is TOO different from the expected maximum: 2009MB above the maximum, and according to jmap and jstat the heap memory allocation didn't even reach its peak (2048-OldSpace + 1534-Eden_+_Survivors).

top 还告诉我代码堆栈是36KB(公平,对于最初的catalina启动器),数据堆栈是7.3GB(代表其余部分)。

top also tells me code stack is 36KB (fair, for the initial catalina starter), and data stack is 7.3GB (representing the rest).

这个tomcat服务器实例是唯一一台在这台机器上运行的实例,并且一直存在一些不稳定性。需要每三天重启一次,因为机器有7647544k RAM可用,没有交换(出于性能原因)。我做了限制的数学运算,并期望按照它们的过程我看到它是一个相当不错的安全边际,留给机器上运行的所有其他服务(除了ssh和top本身之外没有任何一个应该打扰):7468 - 5521 = 1947.对于安全边际而言,这几乎是太多了。

This tomcat server instance is the only one running on this machine, and has been seing some instability. Needs restarting every three days or so, because the machine has 7647544k RAM available, and no swap (for performance reasons). I did the math for the limits, and expecting the process to follow them I saw it was a pretty good security margin to leave for all other services running on the machine (none of which should bother other than ssh and top itself): 7468 - 5521 = 1947. That is almost too much for a "security margin".

所以,我想知道所使用的内存在哪里,为什么不是'达到了极限。如果缺少任何信息,我将很乐意提供。

So, I want to understand where is all that memory being used from, and why isn't the limit obeyed. If any information is lacking, I'll be happy to provide.

推荐答案

简单明了JVM使用的内存比 -Xms -Xmx 和其他命令行参数。

Plain and simple the JVM uses more memory than what is supplied in -Xms and -Xmx and the other command line parameters.

这是关于JVM如何分配和管理内存的非常详细的文章,它并不像你在你的假设中那样简单。问题,值得全面阅读。

Here is a very detailed article on how the JVM allocates and manages memory, it isn't as simple as what you are expected based on your assumptions in your question, it is well worth a comprehensive read.

许多实现中的ThreadStack大小都有最小限制因操作系统和JVM版本而异;如果将限制设置为低于JVM或OS的本机操作系统限制,则会忽略threadstack设置(有时必须设置ulix on * nix)。其他命令行选项以相同的方式工作,当提供的值太小时,默默地默认为更高的值。不要假设传入的所有值都代表实际使用的值。

ThreadStack size in many implementations have minimum limits that vary by Operating System and sometimes JVM version; the threadstack setting is ignored if you set the limit below the native OS limit for the JVM or the OS ( ulimit on *nix has to be set instead sometimes ). Other command line options work the same way, silently defaulting to higher values when too small values are supplied. Don't assume that all the values passed in represent what are actually used.

类加载器和Tomcat有多个,占用大量内存而不是很容易记录。 JIT占用了大量的内存,交易时间空间,这在大多数情况下是一个很好的交易。

The Classloaders, and Tomcat has more than one, eat up lots of memory that isn't documented easily. The JIT eats up a lot of memory, trading space for time, which is a good trade off most of the time.

您引用的数字非常接近我的预期。

The numbers you cite are pretty close to what I would expect.

这篇关于Java进程内存远大于指定的限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆