JVM性能参数调整介绍
JVM内部体系结构
Sun JDK在实现时遵照JVM规范,将内存空间划分为方法区、堆、本地方法栈、PC寄存器、jvm方法栈。
方法区
????方法区主要存放要加载的类的信息,比如类的名称、类的修饰符、类中的静态变量、final类型的常量、field、method等信息。方法区是线程共享的,在一定条件下也会被GC,当方法区要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。
??? 方法区的存储区域对应Permanet Generation(又称,持久代),其默认值为{16MB-64MB},它的大小可以通过如下选项进行调整:
????????????????????????????????????????????最小值:-XX:PermSize
????????????????????????????????????????????最大值:-XX:MaxPermSize
堆
??? 堆用于存储新创建的对象和数组。其大小可以通过如下选项进行调整:
????????????????????????????????????????????最小值:-Xms
????????????????????????????????????????????最大值:-Xmx
????为了让内存回收更有效率,Sun JDK从1.2开始对堆采用分代管理的方式。
????????????????????????heap = New Generation (新生代)+ Old Generation(旧生代)
????其中,New Generation又可以分为Eden Space和Survivor Space,而Survivor Space由两块大小相同的区域组成(通常称为S0、S1)。那么,Eden Space、S0、S1用途上有什么区别吗?先来说说Eden Space,由于堆是线程共享的,因此在堆上分配内存是需要加锁的,这就导致创建对象开销增大,Sun JDK为了提升内存分配的效率,会为每个线程在新生代的Eden Space上分配一块独立的空间,这块空间叫做TLAB(Thread Local Allocation Buffer),因此Eden Space是多个线程独享的连续的内存区域,在一个线程内创建对象,JVM首先考虑在Eden Space的TLAB上分配,如果对象过大或者TLAB空间已用完,那么将在堆上分配。S0、S1也用于新创建对象的存储,他们的另外一个用途是在GC时的临时复制空间。
???????????????????????????????????????????新生代大小值:-Xmn
???????????????????????????????????????????Survivor Space大小:-XX:SurvivorRatio
????旧生代主要存放多次GC后仍然存活的对象,不过,新建的对象也有可能在旧生代上分配。一种是大对象(-XX:PretenureSizeThreshold来确定),另一种是大数组,且数组未引用外部对象。旧生代大小:
????????????????????????????????????????????旧生代大小值=-Xmx 减去 -Xmn
JVM方法栈
????JVM方法栈是线程私有的,其在内存分配上非常高效。当JVM方法栈空间不足时,会抛出StackOverflowError的错误。JVM方法栈可通过如下选项进行调整:
????????????????????????????????????????????JVM方法栈大小:-Xss