Ограничение памяти процесса jvm на ubuntu

Я знаю, что есть такие же вопросы как этот спросили и ответили. Я не удовлетворен ответами, поэтому позвольте мне изложить более подробные сообщения здесь.

Я пытаюсь запустить приложение с помощью JVM OPTs:-Xmx128m -Xms32m -XX:MaxPermSize=64m. Когда приложение началось, и я проверяю использование памяти, набрав cat /proc/10413/status, и я нашел vmsize более 600512 КБ! что намного больше моих настроек. Я хотел бы знать, как ограничить использование памяти 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 ответов


вы не можете контролировать то, что вы хотите контролировать, -Xmx управляет только кучей Java, она не контролирует потребление уроженца JVM, который потребляется совершенно по-разному на основе реализации.

из статьи Спасибо за память (понимание того, как JVM использует собственную память в Windows и Linux )

поддержание кучи и сборщика мусора использовать собственную память вы не можете управление.

больше родной памяти необходимо для поддержания государства система управления памятью, поддерживающая кучу Java. Данные структуры необходимо выделить для отслеживания бесплатного хранения и записи прогресса, когда сбор мусора. Точный размер и характер этих структур данных варьируется в зависимости от реализации, но многие пропорциональны размеру куча.

и компилятор JIT использует собственную память так же, как javac бы

компиляция байт-кода использует собственную память (так же, как статическая компилятор, такой как gcc, требует памяти для запуска), но оба входа ( байт-код) и вывод (исполняемый код) из JIT также должен храниться в собственной памяти. Java-приложения, содержащие много JIT-скомпилированные методы используют больше собственной памяти, чем небольшие приложения.

и тогда у вас есть classloader(ы), которые используют собственную память

приложения Java состоят из классов, определяющих структуру объектов и метод логики. Они также используют классы из класса Java runtime библиотеки (например, java.ленг.String) и может использовать сторонние библиотеки. Эти классы должны храниться в памяти до тех пор, пока они используются. Способ хранения классов зависит от реализации.

Я даже не начну цитировать раздел о потоках, я думаю, вы понимаете, что -Xmx не контролирует то, что вы думаю, он контролирует, он контролирует кучу JVM, а не все идет в кучу JVM, и куча занимает гораздо больше собственной памяти, что вы указываете для управление и бухгалтерия.


как и любой другой процесс в Linux, вы можете ограничить использование памяти процесса JVM (скажем, до 4 ГБ):

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

(технически это фактически виртуальная память, которая является верхней границей для фактического использования памяти. но ulimit по-видимому, не работает с фактическим использованием ОЗУ.)

это приведет к сбою выделения памяти выше предела, предположительно, что приведет к OutOfMemoryError и приложения удалились.