1. 通用配置

-server                                # 运行 JVM 的服务器模式
-Xms1024m                              # 设置初始堆大小为 1024MB
-Xmx4096m                              # 设置最大堆大小为 4096MB
-Xss256k                               # 设置每个线程的栈大小为 256KB
-XX:MetaspaceSize=256m                  # 设置元空间的初始大小为 256MB
-XX:MaxMetaspaceSize=512m              # 设置元空间的最大大小为 512MB
-XX:+UseG1GC                           # 使用 G1 垃圾收集器
-verbose:gc                            # 启用 GC 的详细日志
-Xloggc:/log/gc.log                    # 将 GC 日志输出到指定文件
-XX:+PrintGCTimeStamps                 # 打印 GC 日志中的时间戳
-XX:+PrintGCDetails                    # 打印 GC 详细信息
-XX:+HeapDumpOnOutOfMemoryError        # 在发生 OOM 时生成堆转储文件
-XX:HeapDumpPath=/log/                 # 设置堆转储文件的输出路径
-Djava.security.egd=file:/dev/./urandom  # 优化随机数生成速度
-Dfile.encoding=UTF-8                  # 设置默认的文件编码为 UTF-8

2. 问题描述

2.1 参数描述

2.1.1 -Xms 初始化内存

java运行的内存就像水坝一样,内存在不断的申请和回收,在开发程序的时候我们能大致预估出来后续所需要的内存,这个时候就能对他进行优化了。假设程序从启动到就绪需要150秒,这个过程他会不断的申请开辟内存进行初始化,假设在什么都不配置优化的情况下,假设他从100mb到900mb他不断的开辟申请要内存那么我们想一想,为什么不在一开始的时候就直接给他1gb内存用呢?这样他是不是就不用频繁的开辟申请内存而耗时了?-Xms1024m 就是这个作用,直接初始化1gb内存给他,这样他免去了大量开辟内存的过程,相对的他就加速运行了。

2.1.2 -Xmx 最大申请内存

在正常的情况下他通常会使用2gb内存,但鉴于开发人员的水平是不一致的,写出的代码也是有好有坏,在逻辑上可能写了某些非常耗时大量创建对象的for循环或者批量操作,这种代码是很容易造成内存泄露甚至连java的垃圾回收器都回收不了这些对象内存,那么你想一想,你的系统内存资源是有限的,他在持续开辟申请内存内存泄露而又无法回收,总会达到你的系统阈值的,导致你机器死机。这个时候 -Xmx4096m 就尤为重要了,他能限制最大申请内存,在开发上我们预估一个值,超过这个阈值就是相对的不正常的了。限定死不能再给他开辟更多的内存,防止系统被申请爆宕机。

3. 优化建议

  1. -Xms1024m -Xmx4096m是足以满足大部分java服务的,这个值是比较合理合规的。

  2. 假设我已明确知道他会使用到3.5gb内存,那么我可以直接将最小内存和最大内存配置成为一致,-Xms4096m -Xmx4096m,他几乎不会再开辟内存了因为初始化就已经给了他4g,此刻他的性能会发挥到最大。