作为一名励志成为"神奇宝贝大师"的男人,怎么能连JVM都不懂呢,不然你可能会像智爷那样,一辈子拿不到冠军了。
java能在多平台运行的基础就是java虚拟机了,这边我们不谈论它的内存区域,毕竟jdk7的方法区和jdk8元空间还是有区别的。
//常见参数 -Xms1024m 初始堆大小 -Xmx1024m 最大堆大小 一般将xms和xmx设置为相同大小,防止堆扩展,影响性能。 -XX:NewSize=n:设置年轻代大小 -XX:NewRatio=n:设置年轻代和年老代的比值.如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4 -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值.注意Survivor区有两个.如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5 -XX:MaxPermSize=n:设置持久代大小 -XX:+HeapDumpOnOutOfMemoryError OOM时自动保存堆文件,可以用visualvm分析堆文件 //收集器设置 -XX:+UseSerialGC:设置串行收集器 -XX:+UseParallelGC:设置并行收集器 -XX:+UseParalledlOldGC:设置并行年老代收集器 -XX:+UseConcMarkSweepGC:设置并发收集器 //垃圾回收统计信息 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:filename //并行收集器设置 -XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数.并行收集//线程数. -XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间 -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比.公式为1/(1+n) //并发收集器设置 -XX:+CMSIncrementalMode:设置为增量模式.适用于单CPU情况. -XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数.并行收集线程数. 复制代码
edit configurations
由于笔者一直用的是Springboot,因此这边以Springboot的形式进行示范,在启动项目jar包时添加参数。
java -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC newframe-1.0.0.jar 复制代码
Visual VM 由java编写,已经被jdk集成,通过检测 JVM 中加载的类和对象信息等帮助我们分析内存使用情况,是用来分析java项目 、调优的利器,功能强大。
概述
:显示了项目的jvm参数。
这边的禁用是什么原因呢?相信直播间的观众应该都是有智慧的!
监视
: {} 暂时省略n个字。
线程
: {} 暂时省略n个字。
抽样器
: {} 暂时省略n个字。
top
或者 jps
就能直接查看到Pid。 lsof -i:端口号
,前提是你已经安装了。 ps -ef | grep 项目名
jstat -gcutil 5 1000 复制代码
NewRatio
为1,所以不管是老年代或者新生代发生gc一般都是在200m左右,我们不好分辨是哪个代。其实之前 NewRatio=2
, xmx450m
,发生GC的情况是150m。因此是新生代发生了GC。 4. 知道是新生代发生了GC,基本上已经证明了上述的猜想:有个死循环。通过抽象分析器发现char对象非常大。
5. 接下来可以通过堆dump发现是哪几句代码出现了问题。可以使用jhat
这个工具,文件可以通过Visual VM产生,当然在OOM的情况下,也可以通过参数产生。
jhat -J-Xmx1024M file 复制代码
分析堆dump应该就可以发现了,这边就不分析了,其实是重启项目,映射多个端口,然后等待GC,就比较麻烦。为了更加贴近实际,该项目属于真实项目,已部署到阿里云, www.insistself.cn
,代码来源于github。
最后祝大家新年快乐,找到好工作。希望小智能拿个冠军,都看了十几年了,圆了老玩家的梦吧。