Linux上的Java内存使用

Linux上的Java内存使用,java,linux,memory,Java,Linux,Memory,我正在运行大量的Java应用服务器,它们都在CentOS 5.5 Linux上运行最新版本的Tomcat 6和Sun的Java 6。每台服务器运行多个Tomcat实例 我正在设置-Xmx450m-XX:MaxPermSize=192m参数来控制堆和permgen的增长大小。这些设置适用于所有Java应用服务器上的所有Tomcat实例,总共约70个Tomcat实例 下面是Psi probe报告的其中一个Tomcat实例的典型内存使用情况 Eden = 13M Survivor

我正在运行大量的Java应用服务器,它们都在CentOS 5.5 Linux上运行最新版本的Tomcat 6和Sun的Java 6。每台服务器运行多个Tomcat实例

我正在设置-Xmx450m-XX:MaxPermSize=192m参数来控制堆和permgen的增长大小。这些设置适用于所有Java应用服务器上的所有Tomcat实例,总共约70个Tomcat实例

下面是Psi probe报告的其中一个Tomcat实例的典型内存使用情况

Eden           = 13M
Survivor       = 1.5M 
Perm Gen       = 122M 
Code Cache     = 19M 
Old Gen        = 390M 
Total          = 537M
然而,CentOS报告该特定流程的RAM使用量为7.07亿(根据RSS),其中有1.70亿RAM未被解释

我知道JVM本身和它的一些依赖库必须加载到内存中,所以我决定启动pmap-d来找出它们的内存占用。 根据我的计算,这大约占1700万

接下来是Java线程堆栈,在Linux的32位JVM上,每个线程为320k。 同样,我使用Psi probe计算特定JVM上的线程数,总数是129个线程。So 129+320k=42M

我已经读到NIO在堆外使用内存,但我们在应用程序中不使用NIO

所以在这里,我已经计算了所有我想到的事情。我只解释了“失踪”的170米中的60米


我缺少什么?

Arnar,在JVM初始化过程中,JVM将分配一个由-Xmx和MaxPermSize指定大小的内存(mmap或malloc),因此JVM将在JVM过程开始时为应用程序分配450+192=642m的堆空间。因此,应用程序的java堆空间不是537,而是642m。因此,现在,如果您进行计算,它将为您提供缺少的内存。希望这会有所帮助。

java会预先分配尽可能多的虚拟内存,但驻留端将是您实际使用的内存量。注意:许多库和线程都有自己的overhead,虽然您不使用直接内存,但这并不意味着底层系统都不使用直接内存。e、 如果使用NIO,即使使用heap ByteBuffers,它也会使用一些直接内存


最后,1亿美元大约值8英镑。也许不值得花太多时间担心它。

这不是一个直接的答案,但是,你也考虑过托管吗?这可能会以牺牲一些额外配置为代价节省一些内存。

尝试使用增量垃圾收集器,使用-Xincgc命令行选项。 它在整个GC工作中更具攻击性,并且有一个特殊的异常:它实际上将一些未使用的内存交还给操作系统,这与默认和其他GC选择不同!
这使得JVM消耗的内存大大减少,如果在一台机器上运行多个JVM,这一点尤其好。以牺牲某些性能为代价—但您可能不会注意到这一点。incgc似乎是个小秘密,因为从来没有人提起过。。。它已经存在了亿万年(甚至90年代)。

Arnar,JVM也在使用mmap的所有jar文件,它将使用NIO,并将为RSS做出贡献。我不相信你上面的任何测量都能解释这些。您是否碰巧拥有大量的大型jar文件?如果是这样,用于这些的页面可能是您丢失的内存。

我认为您可以使用Xms开关设置初始堆,并且它将仅在需要时增长到Xmx大小。是的,最初应用程序将获得一个等于-Xms的大小来分配对象,并且它会根据应用程序的要求进一步增长到-Xmx。但是JVM heap是一个大小为-Xms+Perm size的连续空间。当heap增长时,它将从这个预先分配的大小为-Xmx的空间中获得更多的内存。Xms是一个参数,它将帮助JVM决定何时触发GC,因此,每当应用程序完全占用大小为Xms的堆时,JVM就会触发GC并尝试清理垃圾对象,之后如果GC没有清理太多空间来分配应用程序对象请求,JVM就会将堆扩展一定量。(收缩和扩展也是基于太多其他因素)谢谢你的回复,阿尼尔。我刚刚重新启动了有问题的JVM,一旦它完全初始化,RSS内存占用量只有273M。JVM堆+permgen+代码缓存+本机代码大小+线程堆栈当前为248M。所以我不认为整个堆都被分配给了RSS内存。如果我没有指定-Xms或-XX:PermSize,JVM会将-Xms设置为64mb(可用RAM的1/64,即4G),并将XX:PermSize设置为64mb。因为JVM需要一块连续的地址空间,所以会预先分配-Xmx。但这并不意味着所有这些内存都将被使用。在Linux系统上,它将被标记为非活动且不会驻留。这就是为什么您的RSS(驻留集大小)可以更低的原因。Peter,我在许多应用服务器上运行了大约70个Tomcat实例。这个数字真的很重要。那么,如何部署新的应用程序并独立地回滚/删除它们呢。在不支持事务或独立操作的情况下,您可以有效地将根/系统拥有的平面文件用作数据库。我觉得你提供的服务越多,你的解决方案对我来说就越糟糕。如果你有多个盒子,一个系统不能正确部署的可能性对你来说一定是个问题。我自己也问过同样的问题。我发现我们有一堆anon页面(由pmap返回),大小从65536k到65508k不等。不确定这些是什么,但它们占我们内存使用量的三分之一左右。