JVM内存结构分配对java应用程序的性能有很大影响。本文主要介绍设置Java应用程序内存大小以及内存结构的方法,如设置堆的大小,设置新生代的大小,设置持久代的大小,
设置线程栈的大小。
1.设置最大堆内存
java应用程序可以使用的最大堆可以使用-Xmx来进行设置。最大堆指的是新生代和老年代的大小之和的最大值,它是java应用程序的上限。
Runtime.getRuntime().maxMemory()可以得到最大堆。
使用 java -Xmx5M 。。。运行时,设置最大堆的上限为5M。
2.设置最小堆内存
使用JVM参数-Xms来设置系统的最小堆空间,也就是JVM启动时所占有的操作系统内存大小。
java 应用程序在运行时,首先会被分配-Xms指定的内存大小,并尽可能尝试在此大小空间内运行程序。当-Xms指定的大小不能满足应用程序的要求,JVM才会像系统申请更大的空间,直到内存到达-Xmx指定的最大内存为止。如果超过-Xmx指定的大小,则会抛出OutOfMemoryError异常。
如果-Xms指定的过小,则Jvm为了保证系统在指定的内存中运行,就会频繁的进行GC操作以释放失效的内存空间,从而增加Minor GC 和Full GC的操作,对系统性能造成一定影响。
3.设置新生代
参数-Xmn设置新生代的大小,设置一个较大的新生代会减老年代的大小,这个参数对系统性能以及GC行为有很大影响。新生代的大小一般为整个堆空间的1/4 到1/3 左右。
在Hot Spot 虚拟机中,-XX:NewSize 用于设置新生代的初始大小,-XX:MaxNewSize 用于设置新生代的最大值。
4. 设置持久代
持久代不属于堆的一部分。在Hot Spot 虚拟机中,使用 -XX:MaxPermSize设置持久代的最大值,使用-XX:PermSize 设置持久代的初始大小。
持久代的大小直接决定了系统中可以支持多少个类定义和多少个常量。
5.设置线程栈
线程栈是线程的一块私有空间,在JVM中使用 -Xss来设置线程栈的大小。
在线程中进行局部变量的分配,函数调用时,都需要在栈中开辟空间。如果栈空间太小,则没有太多的空间分配给局部变量或者达不到函数调用时的深度,则就会抛出异常,如果栈空间过大,则开设线程所需的内存成本就会上升,系统所支持的线程数就会下降。
java堆也是向操作系统申请空间的。如果堆空间越大,就会导致操作系统可用于线程栈的空间减少,从而导致支持的线程数减少。
6.堆的比例分配
参数-XX:SurvivorRatio 用来设置新生代中 enen空间和s0空间的比例。 s0 和 s1 分别是from 空间和to空间,大小一样,职能相同。 并在Minor GC 互换角色。
7 堆的分配参数总结
与java 应用程序堆内存相关的JVM参数。
-Xms:设置初始堆大小。
-Xmx:设置最大堆大小。
-Xss:设置线程栈大小。
-Xmn: 设置新生代大小
-XX:NewSize 设置新生代初始大小。
-XX:MinHeapFreeRation 设置堆空间的最小空闲比例。当堆空间的空闲内存小于此值时,JVM会自动扩展空间。
-XX:MaxHeapFreeRation 设置堆空间的最大空闲比例。当堆空间的空闲内存大于此值时,JVM会压缩空间,得到一个较小的堆。
-XX:NewRation 设置老年代和新生代的比例。
-XX:SurvivorRatio 设置新生代中 enen 和 s0 比例
-XX:PermSize 设置持久代的初始大小。
-XX:TargetSurvivorRatio。 设置survivor 的使用率。当survivor区的 空间使用率达到此值时,将对象送往老年代。