MAT使用的几张图例技巧


1 下面三个是内存泄漏可能性比较大的地方 

problem suspect 1

problem suspect 2

点击detail 可以看详细  如果发现里面有自己工程包里面的重复的大量对象的创建







2

在dominator_tree 可以对象按照 group by package 分类 便于查看那部分代码出问题

如果自己的工程包下面占用了大量内存 可能就是问题所在


问题一般可能出在 占用最多的地方



选中一个节点 右键查看with incoming reference 可以看 

ps :(ListObjects>with incoming references

 表示的是 当前查看的对象,被外部应用
ListObjects>with outGoing references
表示的是 当前对象,引用了外部对象

菜单

show  objects  by class 可以看具体的class



4

还有一个技巧

如果不容易查到问题 可以比对该项目 之前正确的一个堆文件和一个出问题的堆文件

对比二者差异 容易发现些问题


比如最近的一个线上的问题 莫名服务不可用

对比正常时候堆文件   发现有问题的堆文件 下图二者的比例比平时各高了6个点





右键选择request  弹出菜单选择show  objects  by class 发现如图



object 对象都是300 response 对象也一样



之前这个工程那些出问题的堆文件 这里显示都是300对象 我猜测可能和线上 tomcat 配置有关

原来server.xml 配置

   <Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8"  
           minSpareThreads="25" 
           maxSpareThreads="75"
           enableLookups="false" 
           disableUploadTimeout="true" 
           connectionTimeout="20000"
           acceptCount="300"   
           maxThreads="300" 
           maxProcessors="1000" 
           minProcessors="5"
           useURIValidationHack="false"
           compression="on" 
           compressionMinSize="2048"
           compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
               redirectPort="8443" />

我觉着300可能和maxThreads有关 


maxThreads:Tomcat可创建的最大的线程数,每一个线程处理一个请求;minSpareThreads:最小备用线程数,tomcat启动时的初始化的线程数;maxSpareThreads:最大备用线程数,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程;所以maxThreads决定了tomcat的最大线程阀值,需要设置的大一些


目前调高了 参数

<Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8"  
           minSpareThreads="50" 
           maxSpareThreads="150"
           enableLookups="false" 
           disableUploadTimeout="true" 
           connectionTimeout="20000"
           acceptCount="600"   
           maxThreads="800" 
           maxProcessors="1000" 
           minProcessors="5"
           useURIValidationHack="false"
           compression="on" 
           compressionMinSize="2048"
           compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
               redirectPort="8443" />

看看 后面会不会好 这个问题 (问题描述 没有内存溢出,2-3天线上项目不可用,tomcat 假死状态, pid 在 ,服务不可用)



参考文章:

http://www.jianshu.com/p/d8e247b1e7b2

http://www.tuicool.com/articles/3yMN7z



以下转载


MAT主界面介绍

这里介绍的不是MAT这个工具的主界面,而是导入一个文件之后,显示OverView的界面。

  1. 打开经过转换的hprof文件:

    open hprof
    open hprof

    如果选择了第一个,则会生成一个报告。这个无大碍。

    Leak Suspects
    Leak Suspects
  2. 选择OverView界面:

    System OverView
    System OverView

    我们需要关注的是下面的Actions区域

    • Histogram:列出内存中的对象,对象的个数以及大小

      Histogram
      Histogram
    • Dominator Tree:列出最大的对象以及其依赖存活的Object (大小是以Retained Heap为标准排序的)

    Dominator Tree
    Dominator Tree
    • Top Consumers : 通过图形列出最大的object

      Top Consumers
      Top Consumers
    • Duplicate Class:通过MAT自动分析泄漏的原因

一般Histogram和 Dominator Tree是最常用的。

MAT中一些概念介绍

要看懂MAT的列表信息,Shallow heap、Retained Heap、GC Root这几个概念一定要弄懂。

Shallow heap

Shallow size就是对象本身占用内存的大小,不包含其引用的对象。

  • 常规对象(非数组)的Shallow size有其成员变量的数量和类型决定。
  • 数组的shallow size有数组元素的类型(对象类型、基本类型)和数组长度决定

因为不像c++的对象本身可以存放大量内存,java的对象成员都是些引用。真正的内存都在堆上,看起来是一堆原生的byte[], char[], int[],所以我们如果只看对象本身的内存,那么数量都很小。所以我们看到Histogram图是以Shallow size进行排序的,排在第一位第二位的是byte,char 。

Retained Heap

Retained Heap的概念,它表示如果一个对象被释放掉,那会因为该对象的释放而减少引用进而被释放的所有的对象(包括被递归释放的)所占用的heap大小。于是,如果一个对象的某个成员new了一大块int数组,那这个int数组也可以计算到这个对象中。相对于shallow heap,Retained heap可以更精确的反映一个对象实际占用的大小(因为如果该对象释放,retained heap都可以被释放)。

这里要说一下的是,Retained Heap并不总是那么有效。例如我在A里new了一块内存,赋值给A的一个成员变量。此时我让B也指向这块内存。此时,因为A和B都引用到这块内存,所以A释放时,该内存不会被释放。所以这块内存不会被计算到A或者B的Retained Heap中。为了纠正这点,MAT中的Leading Object(例如A或者B)不一定只是一个对象,也可以是多个对象。此时,(A, B)这个组合的Retained Set就包含那块大内存了。对应到MAT的UI中,在Histogram中,可以选择Group By class, superclass or package来选择这个组。

为了计算Retained Memory,MAT引入了Dominator Tree。加入对象A引用B和C,B和C又都引用到D(一个菱形)。此时要计算Retained Memory,A的包括A本身和B,C,D。B和C因为共同引用D,所以他俩的Retained Memory都只是他们本身。D当然也只是自己。我觉得是为了加快计算的速度,MAT改变了对象引用图,而转换成一个对象引用树。在这里例子中,树根是A,而B,C,D是他的三个儿子。B,C,D不再有相互关系。把引用图变成引用树,计算Retained Heap就会非常方便,显示也非常方便。对应到MAT UI上,在dominator tree这个view中,显示了每个对象的shallow heap和retained heap。然后可以以该节点位树根,一步步的细化看看retained heap到底是用在什么地方了。要说一下的是,这种从图到树的转换确实方便了内存分析,但有时候会让人有些疑惑。本来对象B是对象A的一个成员,但因为B还被C引用,所以B在树中并不在A下面,而很可能是平级。

为了纠正这点,MAT中点击右键,可以List objects中选择with outgoing references和with incoming references。这是个真正的引用图的概念,

  • outgoing references :表示该对象的出节点(被该对象引用的对象)。
  • incoming references :表示该对象的入节点(引用到该对象的对象)。

为了更好地理解Retained Heap,下面引用一个例子来说明:

把内存中的对象看成下图中的节点,并且对象和对象之间互相引用。这里有一个特殊的节点GC Roots,这就是reference chain(引用链)的起点:

Paste_Image.png
Paste_Image.png
Paste_Image.png
Paste_Image.png

从obj1入手,上图中蓝色节点代表仅仅只有通过obj1才能直接或间接访问的对象。因为可以通过GC Roots访问,所以左图的obj3不是蓝色节点;而在右图却是蓝色,因为它已经被包含在retained集合内。
所以对于左图,obj1的retained size是obj1、obj2、obj4的shallow size总和;
右图的retained size是obj1、obj2、obj3、obj4的shallow size总和。
obj2的retained size可以通过相同的方式计算。

GC Root

GC发现通过任何reference chain(引用链)无法访问某个对象的时候,该对象即被回收。名词GC Roots正是分析这一过程的起点,例如JVM自己确保了对象的可到达性(那么JVM就是GC Roots),所以GC Roots就是这样在内存中保持对象可到达性的,一旦不可到达,即被回收。通常GC Roots是一个在current thread(当前线程)的call stack(调用栈)上的对象(例如方法参数和局部变量),或者是线程自身或者是system class loader(系统类加载器)加载的类以及native code(本地代码)保留的活动对象。所以GC Roots是分析对象为何还存活于内存中的利器。

MAT中的一些有用的视图

Thread OvewView

Thread OvewView可以查看这个应用的Thread信息:

Thread OvewView
Thread OvewView

Group

在Histogram和Domiantor Tree界面,可以选择将结果用另一种Group的方式显示(默认是Group by Object),切换到Group by package,可以更好地查看具体是哪个包里的类占用内存大,也很容易定位到自己的应用程序。

Group
Group

Path to GC Root

在Histogram或者Domiantor Tree的某一个条目上,右键可以查看其GC Root Path:

Path to GC Root
Path to GC Root

这里也要说明一下Java的引用规则:
从最强到最弱,不同的引用(可到达性)级别反映了对象的生命周期。

  • Strong Ref(强引用):通常我们编写的代码都是Strong Ref,于此对应的是强可达性,只有去掉强可达,对象才被回收。
  • Soft Ref(软引用):对应软可达性,只要有足够的内存,就一直保持对象,直到发现内存吃紧且没有Strong Ref时才回收对象。一般可用来实现缓存,通过java.lang.ref.SoftReference类实现。
  • Weak Ref(弱引用):比Soft Ref更弱,当发现不存在Strong Ref时,立刻回收对象而不必等到内存吃紧的时候。通过java.lang.ref.WeakReference和java.util.WeakHashMap类实现。
  • Phantom Ref(虚引用):根本不会在内存中保持任何对象,你只能使用Phantom Ref本身。一般用于在进入finalize()方法后进行特殊的清理过程,通过 java.lang.ref.PhantomReference实现。

点击Path To GC Roots --> with all references

Path To GC Roots
Path To GC Roots


文/Gracker(简书作者)
原文链接:http://www.jianshu.com/p/d8e247b1e7b2
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
重点发掘自己每天是否有学到或者感受到新东西,一旦可以感知这些细节,那么心态就会平和、也更容易坚持下来,自然而然就可以等到突破瓶颈的时候。 时间是一个很公平的东西,去体验不同的岗位去寻找自己真正想做的,是一个不错的思路。最怕的是目的性不明确的变化。 事实上那怕我们专注于一个领域,在某些时候还要跳出这个领域,开眼界后再回归方能更上一层楼。 ——祝晓春 手工测试二三事   @ 安琪儿的梦 o_0   提问:一直做手工测试会不会没有前 途 ? 任何一个工作和岗位都会有前途的,但是并不是每个人都会达到很大的高度。关

Spring+SpringMVC+Mybatis整合笔记 - 2016-07-22 22:07:05

出于兴趣,最近在研究SSM,参考着别人的技术资料并结合实际情况,一步一步的跑通了SSM整合的整个过程,现整理如下,希望对于同样对SSM有兴趣的你有所帮助,当然,因本人能力有限,可能有些问题,希望您能够指出来,咱们一起学习进步。   主要技术点: l  Spring + SpringMVC + Mybatis的整合 l  使用maven管理jar包及版本 l  使用mybatis generator代码生成器自动生成代码 l  使用SpringJUnit4ClassRunner进行单元测试   主要配置环境

DOS命令大全(经典收藏) - 2016-07-22 22:07:05

#1 一: net use \\ip\ipc$ " " /user:" " 建立IPC空链接 net use \\ip\ipc$ "密码" /user:"用户名" 建立IPC非空链接 net use h: \\ip\c$ "密码" /user:"用户名" 直接登陆后映射对方C:到本地为H: net use h: \\ip\c$ 登陆后映射对方C:到本地为H: net use \\ip\ipc$ /del 删除IPC链接 net use h: /del 删除映射对方到本地的为H:的映射 net user 用
原文地址:【 http://www.sciencedirect.com/science/article/pii/S0167865514001056 】 一、传统的Mean-Shift 原文地址:【 http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1195991tag=1 】 个人理解(可能存在偏差,会不断改进): Mean-Shift算法用于tracking时,通过最小化两个概率密度函数之间的距离来进行,是一种 非参数技术 。 对于模板中的目标,即
如果你真的就看完了《 packetdrill框架点滴剖析以及TCP重传的一个细节 》,我觉得你应该有一个疑问,那就是RH发行版使用的2.6.32内核真的使用了PRR降窗算法吗?为此,我把故事再撸一遍。         按照标准的2.6.32内核,第一次收到SACK的时候,在进入重传之前,拥塞窗口的值应该是in_flight+1,即2+1=3个段,也就是说可以重传1个段,但是抓包发现重传了2个段,tcpprobe也证实了在进入重传之前,拥塞窗口的值是4,而in_flight的值为2,完全对不上tcp_cwnd
OSSEC linux(server) windows(agent)史上最详细中文配置 作者:谭丙章 E-mail:feifengwind@163.com ossec官方网站: http://www.ossec.net/ ossec帮助文档: http://ossec-docs.readthedocs.org/en/latest/manual/index.html 介绍 SSEC是一款开源的多平台的入侵检测系统,可以运行于Windows, Linux, OpenBSD/FreeBSD, 以及 MacOS等

反汇编mbr - 2016-07-22 19:07:23

https://notelzg.github.io/2016/07/17/disamy-mbr/ 个人博客,排版更好 今天把我们每次开机都用到的MBR,反汇编看看里面的引导代码是怎么样的顺便说一下 MBR 相关的开机过程。以及我们经常用的U盘自启动 程序到底值怎么玩的。 window开机流程 流程 加电--BIOS-- MBR-- DPT-- pbr-- Bootmgr-- bcd-- Winload.exe--- —- 内核加载– 整个windows7系统 细节 在CPU上电之后,若由硬盘启动,则BIO
Members 成员 Members are used for registering and authenticating external users of an Umbraco installation (ie. forum members, intranet users and so forth). Unlike with Document Types and Media Types everything is done in the Members section both defining a
特此说明:我参考了李林锋老师写的《netty权威指南》一书,支持大家买正版书学习。学会了,赶紧写下来,不但为了加深记忆也希望对大家有所帮助! 上节我们讲解了LineBasedFrameDecoder和StringDecoder的使用,如果大家理解了这二个东西,那么这一章学起来将是轻车熟路。话不多说开始吧。 本章我们将讲解一下内容: DelimiterBasedFrameDecoder(可以自动完成以分隔符做结束标志的消息解码)FixedLengthFrameDecoder(可以自动完成对定长消息的解码)

漫谈处理器体系结构 - 2016-07-22 19:07:08

漫谈处理器体系结构 前言: 这篇博客本应该是《 深入理解计算机体系结构 》(第二版)中第一部分第4章处理器体系结构的读后感,但是感觉这样的名字有点low,因为毕竟加入了自己的理解和总结。 ISA(Instruction-Set Architecture) 几乎所有讲体系结构的书都会讲到这个指令集。指令集确实应该是最先说明的问题。一句话概括起来指令集就是说CPU能干什么事。基本常用的指令集包括:传送指令、算术逻辑指令、跳转指令等。是体系结构需要实现的功能。指令集对人类来说是友好的,可阅读的。但对于只认识01