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错误。

 

 

JVM 内存模型

      前面介绍了操作系统寻址空间、用户进程可以占用的内存,那我们再来看看在java process里面有多少内存可以用于java application。

      java 进程的内存分成两大部分:heap和native heap。Available Memory Space – Max Java Heap Size = Native Heap。

      从图中可以看出jvm内存的构成:


                  
 

Java heap– 分配的连续内存区– 通过配置-Xmx在启动的时候占用。Just In Time (JIT) Compiler– JIT运行时数据– 存储动态编译成的二进制代码Virtual Machine Resources:– Debug Engine– Trace Buffers– Dump Buffers– GC InfrastructureJNI Allocations– JNI函数分配的NativeHeapResources to underpin Java Objects– Classes and ClassLoaders(存放在栈中)– Threads(关联Native Thread)– Direct java.nio.ByteBuffers(直接使用NativeHeap)– Sockets(关联Native Socket)