2012-02-05 34 views
9

我知道有同樣的問題,如this one被問及回答。我對這些答案不滿意,所以讓我在這裏提供更多細節信息。限制在Ubuntu上的jvm進程內存

我試着用JVM OPTs啓動我的應用程序:-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 

回答

9

你無法控制你想控制-Xmx只控制Java堆的東西,它不會被JVM,這是消費完全不同基礎上實現控制本地內存消費。

從下面的文章Thanks for the Memory (Understanding How the JVM uses Native Memory on Windows and Linux)

維護堆和垃圾收集器使用您無法控制本機內存。

需要更多的本機內存來維持內存管理系統維護Java堆的狀態。必須分配數據結構 以追蹤空閒存儲並在收集垃圾時記錄進度。這些數據結構 的確切大小和性質隨實現而變化,但許多與堆的大小成正比。

和JIT編譯器使用本機內存一樣javac

字節碼編譯使用本機內存(以同樣的方式,一個靜態 編譯器如gcc,需要內存來運行),但無論是輸入( 字節碼)和來自JIT的輸出(可執行代碼)也必須存儲在本機內存中 。包含許多 JIT編譯方法的Java應用程序使用比小應用程序更多的本機內存。

然後就具有使用本地存儲器

Java應用程序由定義對象結構 和方法邏輯類類加載器(多個)。他們還使用Java運行時類 庫(例如java.lang.String)中的類,並可能使用第三方庫 。這些類需要存儲在內存中的時間長達 。類的存儲方式因實現而異。

我甚至不會開始引用在螺紋上的部分,我覺得你的想法, -Xmx不控制你認爲它控制,它控制JVM堆,不是一切 雲在JVM堆,並且堆佔用了更多本地內存,即您爲管理和簿記指定的內容。

1

像Linux上的任何其他過程中,你可以限制JVM進程的內存使用(說4 GB):

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

(從技術上講這實際上是虛擬內存,這是一個上限實際內存使用情況But ulimit apparently doesn't work with actual RAM usage.

這將導致內存分配超出限制失敗,可能導致OutOfMemoryError和您的應用程序退出。