之前做项目一直是code。之后交给运维人员,但是最近几年一直带项目,经常碰到这样那样的问题。因此也记录下来。下面是当时总结的jvm参数调试。此参数许根据机器内存来设置,我经常看到找我优化的项目,日志经常oom。询问启动参数配置告诉我没有,是默认的,机器是64G内存,上面跑着4个java服务,我心想这样的多少数据才能oom啊。结果找到启动文件发现 堆配置为256,栈最大深度是 64k。询问开发告知他们本地就是默认这个。My god,我问那这些参数有什么作用,不知道,因此我总结下来,也提供给大家,实际情况要根据你们物理机器分配,否则启动不起来。
其次要根据咱们大概评估下,比如我并发是200,每一个请求最多对象有10个,每个对象根据自己定义的属性来,最终评估处一个线程的对象的内存占用。
-XX:MetaspaceSize=128m (元空间默认大小)
-XX:MaxMetaspaceSize=128m (元空间最大大小)
-Xms1024m (堆最大大小)
-Xmx1024m (堆默认大小)
-Xmn256m (新生代大小)
-Xss256k (棧最大深度大小)
-XX:SurvivorRatio=8 (新生代分区比例 8:2)
-XX:+UseConcMarkSweepGC (指定使用的垃圾收集器,这里使用CMS收集器)
-XX:+PrintGCDetails (打印详细的GC日志)
JDK8之后把-XX:PermSize 和 -XX:MaxPermGen移除了,取而代之的是
-XX:MetaspaceSize=128m (元空间默认大小)
-XX:MaxMetaspaceSize=128m (元空间最大大小)
JDK 8开始把类的元数据放到本地化的堆内存(native heap)中,这一块区域就叫Metaspace,中文名叫元空间。
使用本地化的内存有什么好处呢?最直接的表现就是java.lang.OutOfMemoryError: PermGen 空间问题将不复存在,因为默认的类的元数据分配只受本地内存大小的限制,也就是说本地内存剩余多少,理论上Metaspace就可以有多大(貌似容量还与操作系统的虚拟内存有关?这里不太清楚),这解决了空间不足的问题。不过,让Metaspace变得无限大显然是不现实的,因此我们也要限制Metaspace的大小:使用-XX:MaxMetaspaceSize参数来指定Metaspace区域的大小。JVM默认在运行时根据需要动态地设置MaxMetaspaceSize的大小。
查看 jvm 默认配置
java -XX:+PrintCommandLineFlags -version