浅谈JVM堆内存空间调整
实际上每一块自内存区中都会有存在一部分的可变伸缩区,其基本流程:如果空间不足了,则在可变的范围之内扩大内存空间,当一段时间之后发现内存空间没有那么紧张的时候,再将可变空间进行释放。
1、堆内存空间调整参数表
No. | 参数名称 | 描述 |
---|---|---|
01 | -Xms | 设置初始分配大小,默认为物理内存的"1/64" |
02 | -Xmx | 最大分配内存,默认为物理内存的"1/4" |
03 | -XX:+PrintGCDetails | 输出详细的GC处理日志 |
04 | -XX:+PrintGCTimeStamps | 输出GC的时间戳信息 |
05 | -XX:+PrintGCDateStamps | 输出GC时间戳信息(以日期的形式,如2018-04-04T16:53:16.155+0800:) |
06 | -XX:+PrintHeapAtGC | 在GC进行处理的前后打印堆内存信息 |
07 | -Xloggc:保存路径 | 设置日志信息保存文件 |
在整个堆内存的调整策略之中,有经验的人基本上都只会调整两个参数:"-Xmx"(最大内存)、"-Xms"(初始化内存)。
如果要想取得这些内存的整体信息直接利用Runtime类即可
package demo;
/**
* Created by on 2018/4/4.
*/
public class TestDemo {
public static void main(String[] args){
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory(); // 最大内存
long totalMemory = runtime.totalMemory(); // 默认使用总内存
System.out.println("最大内存数:"+maxMemory+"字节、"+(maxMemory/(double)1024/1024)+"MB");
System.out.println("默认使用总内存:"+totalMemory+"字节、"+(totalMemory/(double)1024/1024)+"MB");
}
}
- 根据本机内存大小不同而定
最大内存数:1908932608字节、1820.5MB
使用总内存:128974848字节、123.0MB
发现默认的情况下分配的内存是总内存的"1/4"、而初始化的内存为"1/64";那么也就是说整个内存空间的可变范围(伸缩区):123.0MB~1820.5MB之间,那么现在就可能造成程序的性能下降。
java -Xmx2G -Xms2G TestDemo
那么这个时候要避免伸缩区的可调策略,在执行程序时添加如下命令,将初始大小内存与最大可用内存大小设置为一致,从而提升整个程序的性能。
- 范例:观察GC详细日志
java -Xmx2G -Xms2G -XX:+PrintGCDetails TestDemo
最大内存数:2058354688字节、1963.0MB
默认使用总内存:2058354688字节、1963.0MB
Heap
PSYoungGen total 611840K, used 41984K [0x0000000795580000, 0x00000007c0000000, 0x00000007c0000000)
eden space 524800K, 8% used [0x0000000795580000,0x0000000797e801b8,0x00000007b5600000)
from space 87040K, 0% used [0x00000007bab00000,0x00000007bab00000,0x00000007c0000000)
to space 87040K, 0% used [0x00000007b5600000,0x00000007b5600000,0x00000007bab00000)
ParOldGen total 1398272K, used 0K [0x0000000740000000, 0x0000000795580000, 0x0000000795580000)
object space 1398272K, 0% used [0x0000000740000000,0x0000000740000000,0x0000000795580000)
Metaspace used 2774K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 295K, capacity 386K, committed 512K, reserved 1048576K
下面再编写一个代码,观察GC的触发操作。
- 范例:测试GC处理
package demo;
import java.util.Random;
/**
* Created by on 2018/4/4.
*/
public class TestDemo {
public static void main(String[] args){
Random random = new Random();
String val = "test";
while (true){
val+=val+random.nextInt(999999999)+random.nextInt(999999999);
}
}
}
将堆内存设置小点,可快速看到效果
java -Xmx10m -Xms10m -XX:+PrintGCDetails TestDemo
2、程序运行内存分析工具
$JAVA_HOME: jdk路径
- 可视化的工具:$JAVA_HOME/bin/jvisualvm
- 命令查看: jmap(jmap -heap PID)