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、访问的时候页面转圈,等待要不没法过去 、要不然没返回结果

常见溢出问题
java.lang.OutOfMemoryError: PermGen space //持久栈溢出
java.lang.OutOfMemoryError: Java heap space//堆溢出
java.lang.StackOverflowError   //栈溢出
 
例如:堆溢出

 

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 本节课重点讲解

① 为什么内存溢出之后其他应用也访问不了

② 堆栈的了解

堆: 解决数据存放问题

① 年轻代:new的对象活的不太久、占堆内存3/8

② 年轻代分为:eden占年轻代8/10s0s1区(两个存活区大小相等位置不换)   占年轻代2/10

③ 老年代:new的对象活的比较长、占堆内存5/8

栈: 解决调度运行问题

Jvmjava虚拟机

① Java内存:声明的变量都存放到这里

注意:eden满的是new对象放不进去、应用程序就不能处理用户请求。

年轻代

Eden满了之后淘汰没有用的对象,如果没有引用指向它就是垃圾对象,如果eden满的时候jvm产生一个操作叫垃圾回收操作叫ygcygc只会产生在eden区满的时候,产生ygc的时候应用程序是停止工作的。

ygc做两件事:

① 寻根判断(判断对象哪些是引用的哪些是没有引用的进行分别做标记)知道谁是垃圾对象谁不是垃圾对象

② 把存活的对象移动到s0或者s1区里。非存活对象直接在堆里干掉。Eden里就空了。

③ 清理ygc的时候应用程序是暂停的状态。

④ 清理之后可以放对象了、如果又满了产生ygc把存活的放到s1里、s0里的存活也要放到s1里,s0里空了(s0s1两个存活区大小相当位置互换这时可以互换,就是说一直有一个存活区是空的)。

⑤ 判断s0s1是否都满了,如果都满了就去老年代

ygcfgc的区别:

① ygceden区和两个存活区垃圾回收,内存小、标记时间短、回收快。

② fgc对整个堆和非堆垃圾回收。

老年代

① 大对象直接进入老年代,因为比较大放到年轻代就得一直启动ygc所以直接放到老年代。

② 长期存活的对象进入老年代jvm有个参数控制产生ygc的次数(age默认15次如果这个对象在eden存活16次一直没有被销毁,就说明这个是长期存活对象,直接进入老年代)

③ 对象的动态分配原则s0s1满了之后判断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=2d+l之和是否大于存活区的一半对象放到老年代里。

④ 空间担保原则未能讲解

如果老年代满了,如何处理?

⑤ 对象都进入了老年代,老年代满了之后就产生了fgcfgc整个堆非堆进行垃圾回收。

fgc寻根判断把存活对象保存、非存活对象直接干掉、老年代是最终的归宿。

如果fgc满了就一直产生fgc,如果一直清理不干净就产生了应用程序访问不了。

产生内存溢出、内存泄露

内存溢出和内存泄露区别:内存溢出—指的是结果,满了放不进去了。内存泄露—指的是过程、对象一直回收不掉、释放不掉的过程。

总结:内存分配机制和如何产生fgc(垃圾回收)

① 老年代满了产生fgc

② 显示调用—代码自己调用了system.gcruntime.gc

③ 非堆内存也叫持久带、持久带满了也会产生fgc

④ 空间担保原则—ygc的时候根据一个算法:历史的经验ygc会有多少个对象进入老年代。

⑤ RMI框架基于tcp|ip,自动检查对象是否活着,如果满了就进行fgc、代码里几个小时调用一次像定时任务一样。

⑥ Jmapdump命令对整个堆进行垃圾回收都会产生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  :看内存使用情况和比率

 

posted @ 2019-05-27 13:42  大佳佳  阅读(1117)  评论(0编辑  收藏  举报