性能分析11-内存分析2-内存溢出定位方式

内存:

今天的内容:
	内存溢出了,怎么定位?

	步骤:
	1、验证环境有没有启动起来:http://192.168.226.149:8080/JvmPertest/pertest1


	内存的回收和分配:
	内存段:
		只读读,数据段,堆,栈

		只读段:包括程序的代码和常量,由于只读的,不会再去分配新的内存,所以不会
出现内存泄漏

		数据段:包括全局变量和静态变量,这些变量在定义时就已经确定了大小,也不会
		出现内存溢出

		内存映射段:包括动态链接库和共享内存,其中共享内存由程序动态分配和管理,
		所以,如果程序在分配后忘记回收,就会导致跟堆内存类似的泄漏问题


		内存泄漏的危险非常大,不仅应用程序自己不能访问,系统也不能把他们再次分配给
		其它应用,最终耗尽整个系统的内存

		最终系统可以通过oom机制杀死进程,但进程在oom前,可能引发一连串的反映,
		比如系统内存被占用,其它需要内存的进程就会无法分配新的内存,导致整个
		系统的性能访问都非常很慢


2、配置Tomcat堆栈大小:JAVA_OPTS="-server -Xms128m -Xmx128m -Xmn128m",重启Tomcat

在这里插入图片描述
在这里插入图片描述

3、用性能测试工具(loadrunner,jmeter)发起请求

4、用vmstat来看内存的变化
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

r b swpd free buff cache si so bi bo in cs us sy id wa st
5 0 8120 699548 108 545268 0 0 0 0 3727 421 88 1 11 0 0
5 0 8120 699548 108 545268 0 0 0 1 3792 457 89 1 10 0 0
4 0 8120 699548 108 545268 0 0 0 7 3811 448 89 1 10 0 0
4 0 8120 699516 108 545272 0 0 0 0 3770 548 88 1 11 0 0
1 0 8120 699548 108 545276 0 0 0 0 3753 451 89 1 10 0 0
4 0 8120 699516 108 545280 0 0 0 3 3738 492 88 1 10 0 0
4 0 8120 699516 108 545280 0 0 0 0 3721 413 89 2 9 0 0
4 0 8120 699500 108 545280 0 0 0 0 3760 463 88 2 10 0 0
4 0 8120 699532 108 545280 0 0 0 0 3743 402 88 2 10 0 0

r:如果超过CPU的个数,说明CPU堵塞

内存的free列在不断的变化,并且是越来越小,而buffer和cache基本保持不变,说明,系统中使用的内存
一直在升高。但是这并不能说明内存泄漏

那怎么来确定是不是内存泄漏呢?

1、观察我们的日志输出,有没有错误信息?

2、你的工具请求的接口返回的信息,或者直接在浏览器访问这个接口

输出的错误信息如下:
org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.OutOfMemoryError: Java heap space
org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletionWithError(DispatcherServlet.java:1305)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:979)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause

内存泄露错误
在这里插入图片描述

性能场景的设计:
1、第一次做,不知道哪些接口有性能问题,就需要把主流程里面所有的接口都做性能测试

2、升级的项目,只要做之前用的多,然后会有性能问题的接口

跑多久:一般30分钟足够了,50个并发

看上面的错误信息,已经oom了(OutOfMemoryError: Java heap space)

这个时候怎么办?

3、jmap:用于生成堆栈快照的信息

jmap [option]

option:
-dump: 生成java堆栈快照

-heap: 显示java堆详细信息,使用了哪种回收器,参数配置,分代情况

-histo:显示堆中对象统计信息,包括类,实例数量和合计容量

-F :当虚拟机进程对-dump选项没有响应时,可使用这个选项生成dump快照

-finalizerinfo:显示在F-queue中等待Finalizeer线程执行finalize方法的对象

用jmap生成heap文件:
//format=b:二进制的格式
[root@localhost ~]# jmap -F -dump:format=b,file=testdump.bin pid(14808)
在这里插入图片描述
在这里插入图片描述

把这个dump包,下载到本地

4、将dump包在mat中打开

选择默认,点击完成按钮

5、默认打开的饼图中
从上图可以看到它的大部分功能,在饼图上,会发现转储的大小和数量的类,对象和类加载器
在overview中,饼图给出了一个最大的对象转储,我们来看下面的action标签中的信息:
Histogram: Lists number of instances per class,列出内存中的对象,对象的个数以及大小

Dominator Tree: List the biggest objects and what they keep alive.列出哪个线程,以及线程下面
的哪些对象占用的空间

Top Consumers: Print the most expensive objects grouped by class and by package,通过图形列出
最大的object

Leak Suspects: includes leak suspects and a system overview 通过mat自动分析内存泄漏的原因

点击Histogram这个链接,在这个页面中可以直观的看到哪个类导致的,创建了多少个对象

class name:类名,java类名

objects:类的对象的数量,这个对象被创建了多少个

shallow heap:一个对象内存的消耗大小,不包含对其它对象的引用

Retained heap:是shallow heap综合,也就是该对象被GC之后所能回收到内存的总和

在这里插入图片描述

一般来说,shallow heap堆中的对象是它的大小和保留内存大小相同的对象,是堆内存的数量时,将释放
对象被垃圾收集

主要关注前面两列信息:哪个类,创建了多少个对象

也可以进行搜索

在heap dump overview是它里面,可以看到全局的内存占用信息(了解一下)

Dominator Tree: List the biggest objects and what they keep alive.列出哪个线程,以及线程下面
的哪些对象占用的空间

可以看到com.pertest.PerTest线程最多

Top Consumers:通过图形列出最大的object
这张图展示的是占用内存比较多的对象的分布,下面是具体的一些类和占用

Biggest Top-Level Dominator Classes (Overview)

Biggest Top-Level Dominator Classes:按等级分布的类使用情况,就是按使用次数查看,
java.lang.String被排在第一

Biggest Top-Level Dominator Packages:按照包名看占用,可以根据哪些公共用的到jar或者自己的包
占用

Leak Suspects: includes leak suspects and a system overview:通过mat自动分析内存泄漏的原因

The classloader/component “org.apache.catalina.loader.ParallelWebappClassLoader @ 0xf8280d80”
occupies 83,306,344 (84.71%) bytes. The memory is accumulated in one instance of
“java.lang.Object[]” loaded by “”.

Keywords
java.lang.Object[]
org.apache.catalina.loader.ParallelWebappClassLoader @ 0xf8280d80

从这份报告,看到该图深色区域被怀疑有内存泄漏,可以发现整个heap只有93.8M的内存,但是深色区域就
占用了79.4M,描述信息告诉们主线程占用了大量内存,并且明确指出system class loader加载的
“java.lang.Object[]”实例有内存聚集,并建议用关键字java.lang.Object[]进行检查,mat通过简单的说明
了问题所在,就算使用者没什么处理内存问题的经验,可以点击“details”链接

Accumulated Objects in Dominator Tree
可以看到上面有20 个线程在作业
从图中,可以看到队列中保存了大量的com.pertest.PerTest对象,占用了79兆左右的内存

继续往下看:
ccumulated Objects by Class in Dominator Tree:队列中保存了4,100,056个com.pertest.PerTest,总共
占用了60多兆

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值