1.The first question is for arguments -Xms20m and -Xss2M (the first one is for heap size and second for thread stack size), does m and M have the same meaning and all means MB?
Yes, m and M same meaning and all means MB.
2.The second question is, I have the following code snippet, which I expect get a runtime error very quick since the stack size was set to 512M but the code cause my OS to stuck and never give me a runtime error, anyone knows why is that?
First of all, Java dont used only Heap memory. JVM use non-heap memory in some cases(Call tack, Metaspace etc.). This question answer this situtation. So thread stack use non-heap memory.
Proof:
Run the application XX:NativeMemoryTracking=summary and check used memory with jcmd VM.native_memory command. Related javadoc here.
First, run the application with -XX:NativeMemoryTracking=summary -Xms20m -Xss2M parameters and result:
Native Memory Tracking:
Total: reserved=4581409KB, committed=171605KB
Java Heap (reserved=3121152KB, committed=20480KB)
(mmap: reserved=3121152KB, committed=20480KB)
Thread (reserved=21567KB, committed=21567KB)
(thread #16)
(stack: reserved=21504KB, committed=21504KB)
(malloc=45KB #82)
(arena=18KB #27)
And then, run same application with java -XX:NativeMemoryTracking=summary -Xms20m -Xss512M parameters and result:
Native Memory Tracking:
Total: reserved=7714849KB, committed=3305045KB
Java Heap (reserved=3121152KB, committed=20480KB)
(mmap: reserved=3121152KB, committed=20480KB)
Thread (reserved=3155007KB, committed=3155007KB)
(thread #16)
(stack: reserved=3154944KB, committed=3154944KB)
(malloc=45KB #82)
(arena=18KB #27)
As you can see, heap memory didn't change in both cases but thread native memory is incresed with last case. Because we increase each stack's size. So application never give a runtime error because stack not use heap memory.
Note: Reserved memory represents the total amount of memory our app can potentially use. Conversely, the committed memory is equal to the amount of memory our app is using right now.
Note 2: For every thread, JVM create one run-time stack which is stored here. Every block of this stack is called activation record/stack frame which store methods calls. All local variables of that method are stored in their corresponding frame. After a thread terminate, it’s run-time stack will be destroyed by JVM. It is not a shared resource.