性能测试项目总结之内存泄露和内存溢出_第1页
性能测试项目总结之内存泄露和内存溢出_第2页
性能测试项目总结之内存泄露和内存溢出_第3页
性能测试项目总结之内存泄露和内存溢出_第4页
性能测试项目总结之内存泄露和内存溢出_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、最近大家对性能测试的内存监控挺感兴趣的,有好多文章都是关于内存泄露的。 刚刚做完了一个项目的性能测试, “有幸”也遇到了内存泄露的案例, 所以在此 和大家分享一下。主要从以下几部分来说明, 关于内存和内存泄露、 溢出的概念, 区分内存泄露和 内存溢出;内存的区域划分,了解 GC回收机制;重点关注如何去监控和发现内 存问题;此外分析出问题还要如何解决内存问题。面就开始本篇的内容第一部分 概念众所周知,java中的内存java虚拟机自己去管理的,他不想 C+需要自己去释 放。笼统地去讲, java 的内存分配分为两个部分,一个是数据 堆,一个是栈。 程序在运行的时候一般分配数据堆, 把局部的临时的

2、变量都放进去, 生命周期和 进程有关系。 但是如果程序员声明了 static 的变量, 就直接在 栈中运行的, 进 程销毁了,不一定会销毁 static 变量。另外为了保证 java 内存不会溢出, java 中有垃圾回收机制。 System.gc() 即垃 圾收集机制是指 jvm 用于释放那些不再使用的对象所占用的内存。 java 语言并 不要求jvm有gc,也没有规定gc如何工作。 垃圾收集的目的在于清除不再使 用的对象。gc通过确定对象是否被活动对象引用来确定是否收集该对象。 而其中,内存溢出就是你要求分配的 java 虚拟机内存超出了系统能给你的,系 统不能满足需求,于是产生溢出。内存

3、泄漏是指你向系统申请分配内存进行使用 (new),可是使用完了以后却不归 还(delete),结果你申请到的那块内存你自己也不能再访问,该块已分 配出来的 内存也无法再使用,随着服务器内存的不断消耗,而无法使用的内存越来越多, 系统也不能再次将它分配给需要的程序,产生泄露。一直下去,程序也逐渐 无 内存使用,就会溢出。第二部分 原理JAVA垃圾回收及对内存区划分在 Java 虚拟机规范中,提及了如下几种类型的内存空间:栈内存(Stack):每个线程私有的。堆内存(Heap :所有线程公用的。方法区(Method Area):有点像以前常说的“进程代码段”,这里面存 放了每个加载类的反射信息、类

4、函数的代码、编译时常量等信息。原生方法栈( Native Method Stack ):主要用于 JNI 中的原生代码,平 时很少涉及。而 Java 的使用的是堆内存, java 堆是一个运行时数据区,类的实例 (对象)从中 分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对 象,“垃圾回收”也是主要是和堆内存(Heap有关。垃圾回收的概念就是JAVA虚拟机(JVM回收那些不再被引用的对象内存的过程。 一般我们认为正在被引用的对象状态为“ alive ”,而没有被应 用或者取不到引 用属性的对象状态为“ dead”。垃圾回收是一个释放处于” dead”状态的对象的

5、内存的过程。而垃圾回收的规则和算法被动态的作用于应用 运行当中,自动回 收。JVM的垃圾回收器采用的是一种分代(gen eratio nal)回收策略,用较高的频率对年轻的对象 (young generation) 进行扫描和回收,这种叫做 minor collection ,而对老对象 (old generation) 的检查回收频率要低很多,称为 major collection。这样就不需要每次GC都将内存中所有对象都检查一遍,这种策略有利于实时观察和回收。(Sun JVM 1.3 有两种最基本的内存收集方式:一种称为 copying 或 scavenge, 将所有仍然生存的对象搬到另外

6、一块内存后, 整块内存就可回收。这种方法有效 率,但需要有一定的空闲内存,拷贝也有开销。这种方法用于 minor collection 。 另外一种称为mark-compact,将活着的对象标记出来,然后搬迁到一起连成大 块的内存,其他内存就可以回收了。这种方法不 需要占用额外的空间,但速度 相对慢一些。这种方法用于 major collection. )一些对象被创建出来只是拥有短暂的生命周期,比如 iterators 和本地变量。另外一些对象被创建是拥有很长的生命周期,比如高持久化对象等。然后为每个代分配一到多个内JVM会在分配的内存区内执垃圾回收器的分代策略是把内存区划分为几个代,存区块

7、。当其中一个代用完了分配给他的内存后, 行一个局部的GC(也可以叫minor collection )操作,为了回收处于“ dead” 状态的对象所占用的内存。局部 GC通常要不Full GC要快很多。JVM定义了两个代,年轻代(yong gen eration )(有时称为“ n ursery ”托儿所) 和老年代(old gen eratio n)。年轻代包括 “ Eden space (伊甸园)”和两个“survivor spaces ”。虚拟内存初始化的时候会把所有对象都分配到 Eden space,并且大部分对象也会在该区域被释放。当进行minor GC的时候,VM会把剩下的没有释放

8、的对象从 Eden space 移动到其中一个 survivor spaces 当 中。此外,VM也会把那些长期存活在survivor spaces里的对象移动到 老生代的“ tenured ” space 中。当 tenured gen eratio n 被填满后,就会产生 Full GC,Full GC 会相对比较慢因为回收的内容包括了所有的 live 状态的对象。 pemanet generation 这个代包括了所有 java 虚拟机自身使用的相对比较稳定的 数据对象,比如类和对象方法等。关于代的划分,可以从下图中获得一个概况:lenurcdLdcnspacesVirtualVirtu

9、alVirtualYoungPerm如果垃圾回收器影响了系统的性能,或者成为系统的瓶颈,你可以通过自定义各个代的大小来优化它的性能。使用JConsole,可以方便的查看到当前应用所配置的垃圾回收器的各个参数。想要获得更详细的参数,可以参考以下调优介绍:Tuning Garbage collectio n with the 5.0 HotSpot VMhttp:/java.s un .com/docs/hotspot/gc/i ndex.html最后,总结一下各区内存:Eden Space (heap):内存最初从这个线程池分配给大部分对象。Survivor Space (heap):用于保存在

10、eden space内存池中经过垃圾回收后没有 被回收的对象。Tenured Generation (heap):用于保持已经在 survivor space内存池中存在了一段时间的对象。Permanent Generation (non-heap):保存虚拟机自己的静态 (refective) 数据,例如类(class )和方法(method)对象。Java虚拟机共享这些类数据。这个区 域被分割为只读的和只写的,Code Cache (non-heap):HotSpot Java虚拟机包括一个用于编译和保存本地代码(n ative code )的内存,叫做“代码缓存区”(code cache

11、)第三部分 监控(工具发现问题)谈到内存监控工具,JConsole是必须要介绍的,它是一个用JAVA写的GUI程序, 用来监控VM并可监控远程的VM易用且功能强大。具体 可监控JAVA内存、 JAVA CPU使用率、线程执行情况、加载类概况等,Jconsole需要在JVM参数中配置端口才能使用。由于是GUI程序,界面可视化,这里就不做详细介绍,具体帮助支持文档请参阅性能测试JConsole使用方法总结: npi n/km/test/DocLib/性能测试辅助工具JConsole的使用方法.aspx或者参考SUN官网的技术文档:http:/Java.su n. com/j2se/1.5.0/do

12、cs/guide/ma nageme nt/jcon sole.html http:/Java.s un .com/javase/6/docs/tech no tes/tools/share/jco nsole.html在实际测试某一个项目时,内存出现泄露现象。起初在性能测试的1个小时中,并不明显,而在稳定性测试的时候才发现,应用的HSF调用在经过几个小时 运行后,就出现性能明显下降的情况。在服务日志中报大量HSF超时,但所调用系 统没有任何超时日志,并且压力应用的load都很低。经过查看日志后,认为 应 用可能存在内存泄漏。通过jeon sole以及jmap工具进行分析发现,确实存在 内存泄

13、漏问题,其中PS Old Gen最终达到占用100%的占用。如图所示:从上图可以看到,虽然每次Full GC JVM内存会有部分回收,但回收并不彻底, 不可回收的内存对象会越来越多,这样便会出现以上的一个趋势。在Full GC无法回收的对象越来越多时,最终已使用内存达到系统分配的内存最大值,系统最后无内存可分配,最终down机。第四部分 分析经过开发和架构师对应用的分析, 查看此时内存队列, 看哪个对象占用数据最多, 再利用 jmap 命令,对线程数据分析,如下所示:num #instances #bytes class name1: 92480562: 92480313: 92480684:

14、 1542111前三个 instances665860032 com.taobao.matrix.mc.domain.*295936992 com.taobao.matrix.*147969088 java.util.*堵塞37010664 java.util.Date不断增加, 指代的是同一个代码逻辑, 异步分发的问题,消息,回收多次都无法回收成功。导致内存溢出 此外,对应用的性能单独做了压测, 他的性能只能支撑到一半左右, 故发送消息的TPS应用肯定无法处理过来,导致消息堆积,而 JAVA垃圾回收期认为这些都是有用的对象,导致内存堆积,直至系统崩溃。调优方法 由于具体调优方法涉及到应用的配置信息, 故在此暂不列出, 可以参考性能测试 小组发布的性能测试调优宝典第四部分 总结内存溢出主要是由于代

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论