JVM垃圾收集(Java Garbage Collection)
以JDK1.8为例
Java7模型
Java8模型
在Java8中,永久代已经被移除,被一个成为元空间的区域所取代。
元空间的本质和永久代类似。
元空间与永久代之最大的区别在于:
永久代使用的JVM的堆内存,但是java8以后的元空间并不在虚拟机中而是在使用本机物理内存。
因此,默认情况下,元空间的大小仅受本地内存限制。类的元数据放入native memory,字符串池和类的静态变量放入java堆中,这样可以加载多少类的元数据就不再由MaxPerSize控制,而由系统的实际可用空间来控制。
堆内存调优简介01
- -Xms 设置初始分配大小,默认为物理内存的1/64。
- -Xmx 最大分配内存,默认为物理内存的1/4。
- -XX:+PrintGCDetails 输出详细的GC处理日志。
public static void main(String[] args) {
// 返回Java虚拟机试图使用的最大内存量
long maxMemory = Runtime.getRuntime().maxMemory();
// 返回Java虚拟机中的内存总量
long totalMemory = Runtime.getRuntime().totalMemory();
// 生产环境配置成一样大,避免机器运行时出现峰值,低值的忽高忽低
System.out.println("-Xmx:MAX_MEMORY + " + maxMemory + "(字节)、"+ (maxMemory/(double)1024/1024) + "(MB)");
System.out.println("-Xms:TOTAL_MEMORY + " + totalMemory + "(字节)、"+ (totalMemory/(double)1024/1024) + "(MB)");
}
配置JVM参数
-Xms1024m -Xmx1024m -XX:+PrintGCDetails
打印结果
305664/1024 + 699392/1024 = 981.5
配置JVM参数
-Xms10m -Xmx10m -XX:+PrintGCDetails
public static void main(String[] args) {
String str = "lichi";
while(true) {
str += str + new Random().nextInt(88888888) + new Random().nextInt(999999999);
}
}
最后一次Full GC之后,出现OOM
[GC (Allocation Failure)
[PSYoungGen: 2038K->488K(2560K)] 2038K->736K(9728K), 0.0017218 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure)
[PSYoungGen: 0K->0K(2048K)]
[ParOldGen: 4882K->4862K(7168K)] 4882K->4862K(9216K),
[Metaspace: 3480K->3480K(1056768K)], 0.0095797 secs]
[Times: user=0.01 sys=0.00, real=0.01 secs]