常用的JVM内存分配参数

JVM内存分配参数通常是针对堆来说的,因为 java堆是垃圾收集器(GC)管理的主要区域,是Java虚拟机所管理的内存中最大的一块。

整个堆大小=新生代 + 老年代 + 持久代(相对于HotSpot 类型的虚拟机)

目录

1、-Xmx:设置最大堆空间

2、-Xms:设置最小堆内存

3、-Xmn:设置新生代大小

4、设置持久代

5、堆的比例分配

附:完整参数列表


1、-Xmx:设置最大堆空间

最大堆空间是指新生代和老年代的大小之和的最大值

我们来测试一下

import java.util.Vector;

public class MaxHeap {
	public static void main(String[] args) {
		System.out.println("最大内存"+Runtime.getRuntime().maxMemory()/1024/1024+"M");
		Vector v=new Vector();
		for(int i=0;i<10;i++){
			byte[] b=new byte[1024*1024]; //分配1M
			v.add(b); //强引用,GC不能释放空间
			System.out.println((i+1)+"M 空间被分配");
		}
	}
}

运行结果

最大内存247M
1M 空间被分配
2M 空间被分配
3M 空间被分配
4M 空间被分配
5M 空间被分配
6M 空间被分配
7M 空间被分配
8M 空间被分配
9M 空间被分配
10M 空间被分配

可见本机默认的最大堆内存空间为247M,10M空间也被正常分配了

接下来我们来通过Xmx参数来修改最大堆空间

在菜单栏选择 Run->Run Configurations

运行结果

2、-Xms:设置最小堆内存

最小堆内存即当JVM启动的时候占有的操作系统内存大小的最小值。

java程序在运行时首先分配最小堆内存的内存大小,然后尽可能地尝试在这个空间内运行程序,如果设置的最小堆内存的大小不能满足应用程序时,JVM会向操作系统提出申请堆空间,直到达到最大堆内存大小位置,如果超出了最大堆内存大小,会抛出OOM异常。

如果说最小堆内存设置得太小了,垃圾收集就会频繁地去操作,用于释放失效的内存空间,会对性能有一定的影响。所以最小堆内存空间大小要由具体应用程序来决定。

我们来测试一下:

import java.util.Vector;

public class MinHeap {
	public static void main(String[] args) {
		System.out.println("最大内存"+Runtime.getRuntime().maxMemory()/1024/1024+"M");
		Vector v=new Vector();
		for(int i=0;i<10;i++){
			byte[] b=new byte[1024*1024*10]; //分配10M
			v.add(b); //强引用,GC不能释放空间
			if(v.size()==3){
				v.clear(); //清空内存
			}
			System.out.println("-------");
		}
	}
}

参数设置:最小堆内存为10M,-XX:+PrintGCDetails表示打印GC的详细信息,默认最大堆内存空间为247M

运行结果

最大内存247M
[GC [DefNew: 624K->320K(3072K), 0.0027563 secs][Tenured: 75K->395K(6848K), 0.0070076 secs] 624K->395K(9920K), [Perm : 149K->149K(12288K)], 0.0098816 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
---
[GC [DefNew: 112K->0K(3136K), 0.0004821 secs][Tenured: 20875K->20876K(27332K), 0.0058795 secs] 20988K->20876K(30468K), [Perm : 149K->149K(12288K)], 0.0065446 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
---
[GC [DefNew: 0K->0K(15680K), 0.0004476 secs][Tenured: 41356K->41356K(55280K), 0.0051294 secs] 41356K->41356K(70960K), [Perm : 149K->149K(12288K)], 0.0057963 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
---
[GC [DefNew: 20480K->0K(31104K), 0.0004693 secs] 61836K->41356K(100032K), 0.0005124 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
---
[GC [DefNew: 20480K->0K(31104K), 0.0185877 secs] 61836K->61836K(100032K), 0.0186214 secs] [Times: user=0.01 sys=0.00, real=0.02 secs] 
---
[GC [DefNew: 20480K->0K(31104K), 0.0211021 secs][Tenured: 82316K->41355K(89412K), 0.0150908 secs] 82316K->41355K(120516K), [Perm : 149K->149K(12288K)], 0.0380787 secs] [Times: user=0.03 sys=0.00, real=0.04 secs] 
---
[GC [DefNew: 20480K->0K(31104K), 0.0004966 secs] 61835K->41355K(100032K), 0.0005308 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
---
[GC [DefNew: 20480K->0K(31104K), 0.0039629 secs] 61835K->61835K(100032K), 0.0039979 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
---
[GC [DefNew: 20480K->0K(31104K), 0.0136943 secs][Tenured: 82315K->41355K(89412K), 0.0131430 secs] 82316K->41355K(120516K), [Perm : 149K->149K(12288K)], 0.0284924 secs] [Times: user=0.03 sys=0.00, real=0.03 secs] 
---
[GC [DefNew: 20480K->0K(31104K), 0.0005393 secs] 61835K->41355K(100032K), 0.0006814 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
---
Heap
 def new generation   total 31104K, used 21034K [0x24fe0000, 0x27190000, 0x2a530000)
  eden space 27712K,  75% used [0x24fe0000, 0x2646a9d0, 0x26af0000)
  from space 3392K,   0% used [0x26e40000, 0x26e40000, 0x27190000)
  to   space 3392K,   0% used [0x26af0000, 0x26af0000, 0x26e40000)
 tenured generation   total 68928K, used 41355K [0x2a530000, 0x2e880000, 0x34fe0000)
   the space 68928K,  59% used [0x2a530000, 0x2cd92f80, 0x2cd93000, 0x2e880000)
 compacting perm gen  total 12288K, used 149K [0x34fe0000, 0x35be0000, 0x38fe0000)
   the space 12288K,   1% used [0x34fe0000, 0x35005420, 0x35005600, 0x35be0000)
    ro space 10240K,  45% used [0x38fe0000, 0x39467290, 0x39467400, 0x399e0000)
    rw space 12288K,  54% used [0x399e0000, 0x3a06ace8, 0x3a06ae00, 0x3a5e0000)

当把最小堆内存空间值设大,比如100M:

运行结果

最大内存247M
---
---
[GC [DefNew: 21573K->395K(30720K), 0.0189547 secs] 21573K->20875K(99008K), 0.0192922 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
---
---
[GC [DefNew: 21709K->395K(30720K), 0.0096141 secs] 42189K->31115K(99008K), 0.0096482 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
---
---
[GC [DefNew: 21065K->395K(30720K), 0.0010500 secs] 51785K->31115K(99008K), 0.0010871 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
---
---
[GC [DefNew: 21000K->395K(30720K), 0.0187759 secs] 51720K->51595K(99008K), 0.0188122 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
---
---
Heap
 def new generation   total 30720K, used 21504K [0x24fe0000, 0x27130000, 0x2a530000)
  eden space 27328K,  77% used [0x24fe0000, 0x2647d418, 0x26a90000)
  from space 3392K,  11% used [0x26a90000, 0x26af2f60, 0x26de0000)
  to   space 3392K,   0% used [0x26de0000, 0x26de0000, 0x27130000)
 tenured generation   total 68288K, used 51200K [0x2a530000, 0x2e7e0000, 0x34fe0000)
   the space 68288K,  74% used [0x2a530000, 0x2d730050, 0x2d730200, 0x2e7e0000)
 compacting perm gen  total 12288K, used 149K [0x34fe0000, 0x35be0000, 0x38fe0000)
   the space 12288K,   1% used [0x34fe0000, 0x35005448, 0x35005600, 0x35be0000)
    ro space 10240K,  45% used [0x38fe0000, 0x39467290, 0x39467400, 0x399e0000)
    rw space 12288K,  54% used [0x399e0000, 0x3a06ace8, 0x3a06ae00, 0x3a5e0000)

可见,GC运行次数明显少了

JVM会试图将系统内存尽可能限制在-Xms中,当内存实际使用量触及到了-Xms大小时,会触发FullGC

如果-Xms值比较大时,系统在运行的初期可以减少垃圾收集的次数和耗时

3、-Xmn:设置新生代大小

新生代的内存大小会影响老年代的内存大小,因为他们俩所占的最大堆空间是一定的。一般新生代的大小设置为整个堆的1/4~1/3

等价于hot spot:-XX:NewSize 新生代初始大小 和 -XX:MaxNewSize

import java.util.Vector;

public class testHeap {
	public static void main(String[] args) {
		System.out.println("最大内存"+Runtime.getRuntime().maxMemory()/1024/1024+"M");
		Vector v=new Vector();
		for(int i=0;i<10;i++){
			byte[] b=new byte[1024*1024]; //分配10M
			v.add(b); //强引用,GC不能释放空间			
			if(v.size()==3){
				v.clear(); //清空内存
			}
			System.out.println("---");
		}
	}
}

运行结果

最大内存9M
---
---
[GC [DefNew: 2662K->384K(3712K), 0.0040951 secs] 2662K->2444K(9856K), 0.0041638 secs] [Times: user=0.00 sys=0.02, real=0.01 secs] 
---
---
---
[GC [DefNew: 3562K->0K(3712K), 0.0030396 secs] 5622K->4492K(9856K), 0.0030754 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
---
---
---
[GC [DefNew: 3098K->3098K(3712K), 0.0000183 secs][Tenured: 4492K->2444K(6144K), 0.0052126 secs] 7590K->2444K(9856K), [Perm : 149K->149K(12288K)], 0.0052851 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
---
---
Heap
 def new generation   total 3712K, used 2132K [0x345e0000, 0x349e0000, 0x349e0000)
  eden space 3328K,  64% used [0x345e0000, 0x347f5030, 0x34920000)
  from space 384K,   0% used [0x34920000, 0x34920000, 0x34980000)
  to   space 384K,   0% used [0x34980000, 0x34980000, 0x349e0000)
 tenured generation   total 6144K, used 2444K [0x349e0000, 0x34fe0000, 0x34fe0000)
   the space 6144K,  39% used [0x349e0000, 0x34c43010, 0x34c43200, 0x34fe0000)
 compacting perm gen  total 12288K, used 149K [0x34fe0000, 0x35be0000, 0x38fe0000)
   the space 12288K,   1% used [0x34fe0000, 0x35005448, 0x35005600, 0x35be0000)
    ro space 10240K,  45% used [0x38fe0000, 0x39467290, 0x39467400, 0x399e0000)
    rw space 12288K,  54% used [0x399e0000, 0x3a06ace8, 0x3a06ae00, 0x3a5e0000)

可见一共调用了2次GC以及1次fullgc

我们调大新生代大小为6M时

最大内存9M
---
---
---
---
[GC [DefNew: 4792K->396K(5568K), 0.0035639 secs] 4792K->1420K(9664K), 0.0036134 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
---
---
---
---
[GC [DefNew: 4648K->0K(5568K), 0.0029615 secs] 5672K->3468K(9664K), 0.0030003 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
---
---
Heap
 def new generation   total 5568K, used 2185K [0x345e0000, 0x34be0000, 0x34be0000)
  eden space 4992K,  43% used [0x345e0000, 0x34802428, 0x34ac0000)
  from space 576K,   0% used [0x34ac0000, 0x34ac0088, 0x34b50000)
  to   space 576K,   0% used [0x34b50000, 0x34b50000, 0x34be0000)
 tenured generation   total 4096K, used 3467K [0x34be0000, 0x34fe0000, 0x34fe0000)
   the space 4096K,  84% used [0x34be0000, 0x34f42f98, 0x34f43000, 0x34fe0000)
 compacting perm gen  total 12288K, used 149K [0x34fe0000, 0x35be0000, 0x38fe0000)
   the space 12288K,   1% used [0x34fe0000, 0x35005448, 0x35005600, 0x35be0000)
    ro space 10240K,  45% used [0x38fe0000, 0x39467290, 0x39467400, 0x399e0000)
    rw space 12288K,  54% used [0x399e0000, 0x3a06ace8, 0x3a06ae00, 0x3a5e0000)

只进行了2次GC

4、设置持久代

持久代不属于堆的一部分,持久代的大小直接决定了系统可以支持多少类定义和多久常量。

-XX:PermSize:设置持久代的初始大小

-XX:MaxPermSize:设置持久代的最大值

5、堆的比例分配

一、-XX:SurvivorRatio 设置新生代中的eden空间与s0(from),s1(to)之间的比例关系

因为s0与s1大小是相等的,它们不过是在每次gc后会交换角色,所以-XX:SurvivorRatio=eden/s0=eden/s1

比如:

可见 eden/from=8192/1024=8

Heap
 def new generation   total 9216K, used 891K [0x24fe0000, 0x259e0000, 0x259e0000)
  eden space 8192K,  10% used [0x24fe0000, 0x250befc0, 0x257e0000)
  from space 1024K,   0% used [0x257e0000, 0x257e0000, 0x258e0000)
  to   space 1024K,   0% used [0x258e0000, 0x258e0000, 0x259e0000)
 tenured generation   total 6144K, used 0K [0x259e0000, 0x25fe0000, 0x34fe0000)
   the space 6144K,   0% used [0x259e0000, 0x259e0000, 0x259e0200, 0x25fe0000)
 compacting perm gen  total 12288K, used 148K [0x34fe0000, 0x35be0000, 0x38fe0000)
   the space 12288K,   1% used [0x34fe0000, 0x35005180, 0x35005200, 0x35be0000)
    ro space 10240K,  45% used [0x38fe0000, 0x39467290, 0x39467400, 0x399e0000)
    rw space 12288K,  54% used [0x399e0000, 0x3a06ace8, 0x3a06ae00, 0x3a5e0000)

二、-XX:NewRatio:设置老年代与新生代比例

附:完整参数列表

来自于https://blog.csdn.net/wang379275614/article/details/78471604

JVM参数

并行收集器相关

CMS相关

辅助信息

猜你喜欢

转载自blog.csdn.net/qq_39192827/article/details/86666718