I know there are same questions like this one been asked and answered. I am not satisfied with the answers so let me put into more detail messages here.
I try to start my application with JVM OPTs: -Xmx128m -Xms32m -XX:MaxPermSize=64m. When the app started and I check the memory usage by typing cat /proc/10413/status, and I found the vmsize is more than 600512 kB! which is way bigger than my settings. I'd like to know how to limit the jvm memory usage of the process.
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
解决方案
You can't control what you want to control, -Xmx only controls the Java Heap, it doesn't control consumption of native memory by the JVM, which is consumed completely differently based on implementation.
Maintaining the heap and garbage collector use native memory you can't control.
More native memory is required to maintain the state of the
memory-management system maintaining the Java heap. Data structures
must be allocated to track free storage and record progress when
collecting garbage. The exact size and nature of these data structures
varies with implementation, but many are proportional to the size of
the heap.
and the JIT compiler uses native memory just like javac would
Bytecode compilation uses native memory (in the same way that a static
compiler such as gcc requires memory to run), but both the input (the
bytecode) and the output (the executable code) from the JIT must also
be stored in native memory. Java applications that contain many
JIT-compiled methods use more native memory than smaller applications.
and then you have the classloader(s) which use native memory
Java applications are composed of classes that define object structure
and method logic. They also use classes from the Java runtime class
libraries (such as java.lang.String) and may use third-party
libraries. These classes need to be stored in memory for as long as
they are being used. How classes are stored varies by implementation.
I won't even start quoting the section on Threads, I think you get the idea that
-Xmx doesn't control what you think it controls, it controls the JVM heap, not everything
goes in the JVM heap, and the heap takes up way more native memory that what you specify for
management and book keeping.