JVM01_jmap命令使用
http包含的协议:看文件夹里的loadrunner.pdf,还有状态码
jmap 命令
java可以跨平台—java在虚拟机里运行
把网盘里的test1.war包放到tomcat的webapps下 启动tomcat 访问:http://192.168.1.104:8080/test1/init1.jsp
1、/opt/apache-tomcat-8.5.41/conf/server.xml 这个位置配置项目路径,不是所有公司都是默认路径为了安全都不会使用默认路径,要写绝对路径。
2、查看一下进程号、看看进程是不是存在:
3、查看端口号:/opt/apache-tomcat-8.5.41/conf/server.xml 这里查看8080
还可以用命令查看
jmeter进行压测—看结果
内存溢出:
1、访问的时候页面转圈,等待要不没法过去 、要不然没返回结果
permGen space:持久溢出
Java heap space:堆溢出——最常见的溢出
StackOverflowError:栈溢出
① 查看日志cd /usr/tomcat/apache-tomcat-8.5.24/logs
查看日志命令:tail -f catalina.out
② Ps -ef|grep java jstat -gcutil 进程号 1000这个是每一秒打印一下进程
l 本节课重点讲解
① 为什么内存溢出之后其他应用也访问不了
② 堆栈的了解
l 堆: 解决数据存放问题
① 年轻代:new的对象活的不太久、占堆内存3/8。
② 年轻代分为:eden区占年轻代8/10和s0和s1区(两个存活区大小相等位置不换) 占年轻代2/10。
③ 老年代:new的对象活的比较长、占堆内存5/8。
l 栈: 解决调度运行问题
Jvm: java虚拟机
① Java内存:声明的变量都存放到这里
注意:eden满的是new对象放不进去、应用程序就不能处理用户请求。
年轻代
Eden满了之后淘汰没有用的对象,如果没有引用指向它就是垃圾对象,如果eden满的时候jvm产生一个操作叫垃圾回收操作叫ygc、ygc只会产生在eden区满的时候,产生ygc的时候应用程序是停止工作的。
ygc做两件事:
① 寻根判断(判断对象哪些是引用的哪些是没有引用的进行分别做标记)知道谁是垃圾对象谁不是垃圾对象
② 把存活的对象移动到s0或者s1区里。非存活对象直接在堆里干掉。Eden里就空了。
③ 清理ygc的时候应用程序是暂停的状态。
④ 清理之后可以放对象了、如果又满了产生ygc把存活的放到s1里、s0里的存活也要放到s1里,s0里空了(s0、s1两个存活区大小相当位置互换这时可以互换,就是说一直有一个存活区是空的)。
⑤ 判断s0和s1是否都满了,如果都满了就去老年代。
ygc和fgc的区别:
① ygc对eden区和两个存活区垃圾回收,内存小、标记时间短、回收快。
② fgc对整个堆和非堆垃圾回收。
老年代
① 大对象直接进入老年代,因为比较大放到年轻代就得一直启动ygc所以直接放到老年代。
② 长期存活的对象进入老年代、jvm有个参数控制产生ygc的次数(age默认15次如果这个对象在eden存活16次一直没有被销毁,就说明这个是长期存活对象,直接进入老年代)
③ 对象的动态分配原则s0和s1满了之后判断age对象。从age=1开始,存活区里相同的age对象大小之和是否大于存活区的一半大小,如果是下次ygc时候会把大于等于age放到老年代里。
对象 a b c d e f h i j k m l n
1 3 3 2 10 9 8 5 4 3 1 2 12
计算存活区里age对象的值,计算age里所有相同对象之和,例如:age =1 那就是a+m是否大于存活区的一半,放入老年代区域,如果age=1不满足,就计算age=2,d+l之和是否大于存活区的一半对象放到老年代里。
④ 空间担保原则未能讲解
如果老年代满了,如何处理?
⑤ 对象都进入了老年代,老年代满了之后就产生了fgc、fgc对整个堆和非堆进行垃圾回收。
fgc寻根判断把存活对象保存、非存活对象直接干掉、老年代是最终的归宿。
如果fgc满了就一直产生fgc,如果一直清理不干净就产生了应用程序访问不了。
产生内存溢出、内存泄露
内存溢出和内存泄露区别:内存溢出—指的是结果,满了放不进去了。内存泄露—指的是过程、对象一直回收不掉、释放不掉的过程。
总结:内存分配机制和如何产生fgc(垃圾回收)
① 老年代满了产生fgc。
② 显示调用—代码自己调用了system.gc和runtime.gc。
③ 非堆内存也叫持久带、持久带满了也会产生fgc。
④ 空间担保原则—ygc的时候根据一个算法:历史的经验ygc会有多少个对象进入老年代。
⑤ RMI框架基于tcp|ip,自动检查对象是否活着,如果满了就进行fgc、代码里几个小时调用一次像定时任务一样。
⑥ Jmap和dump命令对整个堆进行垃圾回收都会产生fgc、这两个命令触发fgc。
⑦ 栈-非堆会影响cpu很高、堆会影响内存溢出—堆内存产生的性能问题内存溢出、
问题:
fgc很频繁,如何减小频率和时间。
ygc频繁—ygc很频繁每次如果时间很长、如果ygc每次回收1s时间过长也需要考虑。
查看内存泄露的时候不能重启服务、重启后就查看不到异常情况了
堆
内存溢出如何定位原因
1、jmap命令:
jmap用法:
1、jmap 选项 pid
选项:
空
-heap
-histo[:live]
-permstat
-dump 堆内存<dump-options>
dump还有选项
内存泄漏—出问题不要重启,重启后没有日志了,要保存快照堆得信息、栈的信息
举例子:
ps -ef|grep java|grep -v grep|awk'{print{$2}}'|xargs kill -9
查询进程,过滤掉grep本身命令,awk 过滤到进程号,执行杀死
jmap 进程号
jmap -heap 2587 堆内存的大小和基本配置信息
jmap -histo 2587 看哪个类占用的空间大,分析类 看top前20应用程序的方法或者类——有没有导致内存溢出,
分析:init1.jsp
方法里的对象没有被释放掉,导致内存溢出!
如果top20没有开发写的类或者方法,
原始方法:jmap -dump:live,format=b,file=heap.bin 2587 --heap.bin文件
解析:jhat heap.bin
如果报错Java heap space 解析的时候就要加:jhat -J-mx1024m heap.bin
现在用mat工具查看
打开—MemoryAnalyzer.exe 分析内存溢出 a、b大对象
分析这里的class Name —类名和方法名
总结堆内存溢出:
首先用jmap 命令:jmap -histo 2587 >1.txt 分析前几个占用最大,如果没有查看到
(前提条件:就是有大对象、内存溢出、访问一段时间堆内有东西系统加载一些初始化的文件)
最早命令现在已经不用了,就用命令分析:jmap -dump:live,format=b,file=heap.bin 2587 jhat -head1.bin分析给端口号,用ip+端口号访问
jmap不能直接定位分析不出来,就用mat分析内存泄漏 —heap.bin 用工具打开
分析堆—堆内存活动使用情况、堆内存大小占用比率
每隔2000s 打印一次共计打印5次
jstat -gcutil 2587 2000 5 //查看内存情况 -看gc的活动情况,耗时情况
E:eden区
O:老年代
ygc比fgc次数多
Ygct:ygc耗时
Fgct:fgc耗时
Gct:ygc+fgc时间之和
总结
jmap -heap 3312
jmap -histo 2587 --定位内存泄漏原因
jmap -dump:live,format=b,file=heap.bin 3312 --分析内存溢出,jmap -histo分析不出来需要把堆dump下来用工具进行分析,jmap-dump会fgc和ygc各加一次
mat 分析
jstat :看内存使用情况和比率