文章插图
此时free memory就又缩水了,不过total memory是没有变化的 。Java会尽可能将total mem的值维持在最小堆内存大小
byte[] b = new byte[10 * 1024 * 1024];System.out.println("分配了10M空间给数组");System.out.println("Xmx=" + Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");//系统的最大空间System.out.println("free mem=" + Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");//系统的空闲空间System.out.println("total mem=" + Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");
文章插图
这时候我们创建了一个10M的字节数据,这时候最小堆内存是顶不住的 。我们会发现现在的total memory已经变成了15M,这就是已经申请了一次内存的结果 。
此时我们再跑一下这个代码
System.gc();System.out.println("Xmx=" + Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");//系统的最大空间System.out.println("free mem=" + Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");//系统的空闲空间System.out.println("total mem=" + Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");
文章插图
此时我们手动执行了一次fullgc,此时total memory的内存空间又变回5.5M了,此时又是把申请的内存释放掉的结果 。
#4.2 调整新生代和老年代的比值-XX:NewRatio --- 新生代(eden+2*Survivor)和老年代(不包含永久区)的比值
例如:-XX:NewRatio=4,表示新生代:老年代=1:4,即新生代占整个堆的1/5 。在Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置 。
#4.3 调整Survivor区和Eden区的比值-XX:SurvivorRatio(幸存代)--- 设置两个Survivor区和eden的比值
例如:8,表示两个Survivor:eden=2:8,即一个Survivor占年轻代的1/10
#4.4 设置年轻代和老年代的大小-XX:NewSize --- 设置年轻代大小
-XX:MaxNewSize --- 设置年轻代最大值
可以通过设置不同参数来测试不同的情况,反正最优解当然就是官方的Eden和Survivor的占比为8:1:1,然后在刚刚介绍这些参数的时候都已经附带了一些说明,感兴趣的也可以看看 。反正最大堆内存和最小堆内存如果数值不同会导致多次的gc,需要注意 。
#4.5 小总结根据实际事情调整新生代和幸存代的大小,官方推荐新生代占java堆的3/8,幸存代占新生代的1/10
在OOM时,记得Dump出堆,确保可以排查现场问题,通过下面命令你可以输出一个.dump文件,这个文件可以使用VisualVM或者Java自带的Java VisualVM工具 。
-Xmx20m -Xms5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=你要输出的日志路径
一般我们也可以通过编写脚本的方式来让OOM出现时给我们报个信,可以通过发送邮件或者重启程序等来解决 。#4.6 永久区的设置
-XX:PermSize -XX:MaxPermSize
初始空间(默认为物理内存的1/64)和最大空间(默认为物理内存的1/4) 。也就是说,jvm启动时,永久区一开始就占用了PermSize大小的空间,如果空间还不够,可以继续扩展,但是不能超过MaxPermSize,否则会OOM 。tips:如果堆空间没有用完也抛出了OOM,有可能是永久区导致的 。堆空间实际占用非常少,但是永久区溢出 一样抛出OOM 。
#4.7 JVM的栈参数调优#4.7.1 调整每个线程栈空间的大小可以通过-Xss:调整每个线程栈空间的大小
JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K 。在相同物理内存下,减小这个值能生成更多的线程 。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右
#4.7.2 设置线程栈的大小
-XXThreadStackSize:设置线程栈的大小(0 means use default stack size)
这些参数都是可以通过自己编写程序去简单测试的,这里碍于篇幅问题就不再提供demo了#4.8 (可以直接跳过了)JVM其他参数介绍形形色色的参数很多,就不会说把所有都扯个遍了,因为大家其实也不会说一定要去深究到底 。
#4.8.1 设置内存页的大小
-XXThreadStackSize:设置内存页的大小,不可设置过大,会影响Perm的大小
#4.8.2 设置原始类型的快速优化-XX:+UseFastAccessorMethods:设置原始类型的快速优化
#4.8.3 设置关闭手动GC-XX:+DisableExplicitGC:设置关闭System.gc()(这个参数需要严格的测试)
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 二维码的升级版「三维码」你使用过吗?
- 保证健康的宝贵食物你掌握几种
- 开车那么久,你知道该如何保养爱车吗?
- 平板支撑有多厉害?坚持做一个月你就知道了
- 如果你正准备换发型,别错过这30款
- 蚊子最爱叮什么血型的人,你知道吗?
- 揠苗助长的意思和寓意 拔苗助长告诉我们什么道理
- 见男友的小tips是什么梗 见男友的小tips
- 中考成绩怎么查?
- 小叶紫檀|木质界的帝王之木,你了解多少?