jvm最终表现为一个java进程,也是一个操作系统进程。因此jvm的内存最大就是进程的内存,进程所能占用的内存决定于OS的寻址空间和内存模型。
32位操作系统的寻址空间为:2^32 0x00000000 – 0xFFFFFFFF 4GB
64位操作系统的寻址空间为:2^64 0x0000000000000000 – 0xFFFFFFFFFFFFFFFF 16 EiB
并不是所有的寻址空间都能给用户进程使用,操作系统的kernel、runtime support libraries需要占用一定的内存,这些内存占用多少、占用什么地址段和操作系统内存模型相关,不同的操作系统用户能用的地址空间不同。
32bit User Space Available to the Java Process
64位操作系统由于寻址空间巨大,基本不会出现内存不够用的情况,因此就不详细介绍其内存模型了。
64 bit User Space Available to the Java Process
了解了操作系统的寻址空间和内存模型后,你就可以了解jvm作为一个java process,所能占用用户内存是多大了。
栈是运行时的单位,而堆是存储的单位。
栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;堆解决的是数据存储的问题,即数据怎么放、放在哪儿。Java变量中基本类型存放在栈中,引用类型存放在heap中,因为基本类型的长度不变,不需要动态扩展。
在Java中一个线程就会相应有一个线程栈(-Xss)与之对应,而堆则是所有线程共享的。栈因为是运行单位,里面存储的信息都是跟当前线程(或程序)相关信息的。包括局部变量、程序运行状态、方法返回值等等;而堆只负责存储对象信息。线程栈过小会出现java.lang.StackOverflowError错误。
前面介绍了操作系统寻址空间、用户进程可以占用的内存,那我们再来看看在java process里面有多少内存可以用于java application。
java 进程的内存分成两大部分:heap和native heap。Available Memory Space – Max Java Heap Size = Native Heap。
从图中可以看出jvm内存的构成: