在ubuntu上限制jvm进程内存

时间:2012-02-05 00:05:34

标签: java linux memory jvm

我知道有同样的问题,例如this one已被问及回答。我对答案不满意,所以让我在这里详细介绍一下。

我尝试使用JVM OPT启动我的应用程序:-Xmx128m -Xms32m -XX:MaxPermSize=64m。当应用程序启动时,我通过键入cat /proc/10413/status检查内存使用情况,我发现vmsize超过600512 kB!这比我的设置大。我想知道如何限制进程的jvm内存使用情况。

Name:   java
State:  S (sleeping)
Tgid:   10413
Pid:    10413
PPid:   1
TracerPid:      0
Uid:    1001    1001    1001    1001
Gid:    1007    1007    1007    1007
FDSize: 128
Groups: 1001 1007
**VmPeak:   728472 kB**
**VmSize:   600512 kB**
VmLck:         0 kB
VmHWM:    298300 kB
VmRSS:    280912 kB
VmData:   647804 kB
VmStk:       140 kB
VmExe:        36 kB
VmLib:     13404 kB
VmPTE:       808 kB
VmSwap:        0 kB
Threads:        33
SigQ:   0/31522
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 2000000181005ccf
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed:   f
Cpus_allowed_list:      0-3
Mems_allowed:   00000000,00000001
Mems_allowed_list:      0
voluntary_ctxt_switches:        3
nonvoluntary_ctxt_switches:     2

2 个答案:

答案 0 :(得分:10)

您无法控制要控制的内容-Xmx仅控制Java堆,它不控制本机内存的消耗JVM,根据实现情况完全不同地使用。

来自以下文章Thanks for the Memory ( Understanding How the JVM uses Native Memory on Windows and Linux )

维护堆和垃圾收集器使用您无法控制的本机内存。

  

需要更多的本机内存来维护状态   内存管理系统维护Java堆。数据结构   必须分配以跟踪免费存储并记录进度   收集垃圾。这些数据结构的确切大小和性质   随实施而变化,但许多与大小成正比   堆。

并且JIT编译器使用本机内存,就像javac

一样
  

字节码编译使用本机内存(与静态内存相同)   编译器如gcc需要内存运行),但两者都是输入(   字节码)和JIT的输出(可执行代码)也必须   存储在本机内存中。包含许多的Java应用程序   JIT编译的方法比较小的应用程序使用更多的本机内存。

然后你有使用本机内存的类加载器

  

Java应用程序由定义对象结构的类组成   和方法逻辑。它们还使用Java运行时类中的类   库(如java.lang.String)并可能使用第三方   库。只要这些类需要存储在内存中   他们正在被使用。如何存储类因实现而异。

我甚至不会开始引用关于Threads的部分,我想你明白了 -Xmx不控制您认为它控制的内容,它控制JVM堆,而不是所有内容 进入JVM堆,并且堆占用了您指定的更多本机内存 管理和簿记。

答案 1 :(得分:1)

与Linux上的任何其他进程一样,您可以限制JVM进程的内存使用量(比如说4 GB):

$ ulimit -v 4194304
$ java ...   # execute your Java program

(从技术上讲,这实际上是虚拟内存,它是实际内存使用量的上限。But ulimit apparently doesn't work with actual RAM usage.

这会导致超出限制的内存分配失败,可能会导致OutOfMemoryError并且您的应用程序退出。