-Xmx:设置JVM最大堆内存。最大堆内存指的是新生代和老年代的大小之和的了大值,它是Java应用程序的堆上限。
Java堆分为新生代和老生代两部分,新生代用于存放刚刚产生的对象和年经的对象,如果对象一直没有被回收,生存的足够长,老年对象就会移入老年代。
新生代又可进一步分为eden、surivor space0(s0或from space)和survivor space1(s1或to space)。eden大部分对象刚刚建立时,通常会放在这里, s0,s1存放其中的对象至少经历了一次垃圾回收,并得以幸存。如果surivor的对象到指定年龄仍未被回收,则有机会进入老年区(tenured)。
-XX:NewRatio=4:设置年经代比例(包括Eden和两个Survivor区[from(s0)和to(s1)区即存放的对象至少经历了一次垃圾回收]。设置4,表示年经代与年老代的比值为1:4,即占整个堆栈1/5
以下例子堆内存20M,新生代和年才代比为1:2,即新生代=1/3堆内存=6M多。年老代=2/3堆内存=12M多
-XX:SurvivorRatio=8:设置年经代中的Eden区与Survivor区的大小比值.设置4表示,两个Survivor区与一个Eden区的比值为2:8.一个Survivor区整个年经代的1/10.eden=Xmn-(Xmn/1+1+8)*2=8M,survivor=1*2=2M
以下例子新生代大小10M eden space 8192K,from space和to space为1024,
-XX:SurvivorRatio可以设置eden与surivor区的比例,-XX:NewRatio可设置老年代与新生代比例。可通过-XX:+PrintGCDetails参数打印出堆的实际大小。
-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,年经代对象不经过Survivor区,直接进入年老代。
-Xms:设置系统的最小空间,也就是JVM启动时,所占据的操作系统内在大小,Java应该用程序在运行时,首先会被分配-Xms指定的内存大小,并尽可能尝试在这个空间段内运行程序。当-Xms内存大小无法满足时,JVM会向操作系统申请更多内存,直到内在达到-Xmx最大内在为止
JVM会试图将系统内存尽可能限制在-Xms中,因此,当内在实际使用量触及-Xms指定的大小时。会触发Full GC。因此指-Xms设置直-Xmx时。可以在系统运行初期减少GC的次数和耗时
public class TestXmxXms {
public static void main(String[] args) {
java.util.Vector v = new java.util.Vector();
for (int i =1; i <= 10;i++) {
byte[] b = new byte[1024*1024];
v.add(b);
if (v.size() == 3) {
v.clear();
}
}
}
}
执行结果如下:进行了10次Minor GC(发生在新生代的垃圾收集)和2 次Full GC(老年代的垃圾回收)
如果使用 -Xmx11M -Xms11M -verbose:gc 结果
-Xmn:设置新生代的大小,设置一个大的新生代后减少老年代的大小。这个参数对GC有很大的影响。新生代的空间一般设置为整个堆空间的1/4到1/3左右。
如果使用 -Xmx11M -Xms11M -Xmn2M -verbose:gc结果(Minor GC由4次增加为9次)
在Hot Sport虚拟机里。可设置-XX:NewSize(新生代初始大小),-XX:MaxNewSize(设置新生代的最大值),通常-Xmn可以满足要求.设置-Xmn相当于设置-XX:NewSize和-XX:MaxNewSize。若设置不同,可能会导致内存震荡。
设置持久代
持久代(方法区)不属于堆的一部分。在Hot Spot虚拟机,使用-XX:MaxPermSize(设置持久代最大值),-XX:PermSize设置持久初始值
持久代的大小直接决定了系统可以支持多少个类定义和多少常量。
以下例子通过javassist动态生成大量classs类应用
import javassist.ClassPool;
import javassist.CtClass;
public class TestPermSize {
public static void main(String[] args) {
int i = 0;
try {
for (i=1;i<=Integer.MAX_VALUE;i++) {
CtClass c = ClassPool.getDefault().makeClass("Geym" + i);
c.setSuperclass(ClassPool.getDefault().get("JavaBeanObject"));
Class clz = c.toClass();
JavaBeanObject v = (JavaBeanObject)clz.newInstance();
}
} catch (Exception e) {
System.out.println("Create New Classes count is " + i);
e.printStackTrace();
}
}
}
当用-XX:PermSize=4M -XX:MaxPermSize=4M时。最多可生成5021个对象时,抛出异常
当使用-XX:PermSize=4M -XX:MaxPermSize=8M时。可生成11415个对象
设置线程栈
-Xss可以设置线程栈大小,线程进行局部变量分配,函数调用时,需要在栈中开辟空间。如果栈空间分配太小,那么线程在运行时。可能没有足够的空间分配局部变量或达不到足够的函数调用深度,导致程序退出;如果栈空间太大,那么开线程所需要的内存成本就会上升,系统所能支持的线程总数就会下降。
public class TestXss {
public static class MyThread extends Thread {
public void run() {
try {
Thread.sleep(10000);
} catch (Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int i = 0;
try {
for (i = 0; i < 10000; i++) {
new MyThread().start();
}
} catch (OutOfMemoryError e) {
System.out.println("count thread is " + i);
e.printStackTrace();
}
}
}
此时的OutOfMemoryError,它不是因数堆内存不够而溢出,而是因为栈空间不够,为了赢得更多的栈空间,可以适时减少堆的大小,从而尽可能避免这种OutOfMemoryError异常。
-XX:MinHeapFreeRatio:设置堆空间最小空间比例。当堆空间的空闲内存小于这个数值时,JVM便会扩展空间
-XX:MaxHeapFreeRatio:设置堆空间的最大空间比例。当堆空间的空闲内存大于这个数值时,便会压缩堆空间,得到一个较小的堆。
-XX:NewSize:设置新生代的大小
-XX:TargetSurvivorRatio:设置 survivior区的可使用率。当survivior区的空间使用率达到这个数值时,会将对象送入老年代