- 浏览: 402806 次
- 性别:
- 来自: 长春
文章分类
最新评论
-
milkyTea_:
...
学习:二维码、QR码、J4L-QRCode、java -
xunke515:
请问如何更换其他用户,注销了从新登录的时候选择么?
Hadoop启动时出现Unrecognized option: -jvm 和 Could not create the Java virtual machine -
_copythat:
学习:二维码、QR码、J4L-QRCode、java -
小fi(FD):
楼主,你好,关于你发表的《基于动态表单的Java不确定字段数报 ...
基于动态表单的Java不确定字段数报表项目实现 -
rmn190:
受用了。多谢分享!
SD2见闻--参加PPT制作秘笈沙龙
性能测试项目总结之内存泄露和内存溢出
2009年11月19日 由 yunshuai
留言 »
最近大家对性能测试的内存监控挺感兴趣的,有好多文章都是关于内存泄露的。
刚刚做完了一个项目的性能测试,“有幸”也遇到了内存泄露的案例,所以在此和大家分享一下。
主要从以下几部分来说明,关于内存和内存泄露、溢出的概念,区分内存泄露和内存溢出;内存的区域划分,了解GC回收机制;重点关注如何去监控和发现内存问题;此外分析出问题还要如何解决内存问题。
下面就开始本篇的内容
第一部分 概念
众所周知,java中的内存java虚拟机自己去管理的,他不想C++需要自己去释放。笼统地去讲,java的内存分配分为两个部分,一个是数据堆,一个是栈。程序在运行的时候一般分配数据堆,把局部的临时的变量都放进去,生命周期和进程有关系。但是如果程序员声明了static的变量,就直接在栈中运行的,进程销毁了,不一定会销毁static变量。
另外为了保证java内存不会溢出,java中有垃圾回收机制。 System.gc()即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。垃圾收集的目的在于清除不再使用的对象。gc通过确定对象是否被活动对象引用来确定是否收集该对象。
而其中,内存溢出就是你要求分配的java虚拟机内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问,该块已分配出来的内存也无法再使用,随着服务器内存的不断消耗,而无法使用的内存越来越多,系统也不能再次将它分配给需要的程序,产生泄露。一直下去,程序也逐渐无内存使用,就会溢出。
第二部分 原理
JAVA垃圾回收及对内存区划分
在Java虚拟机规范中,提及了如下几种类型的内存空间:
◇栈内存(Stack):每个线程私有的。
◇堆内存(Heap):所有线程公用的。
◇方法区(Method Area):有点像以前常说的“进程代码段”,这里面存放了每个加载类的反射信息、类函数的代码、编译时常量等信息。
◇原生方法栈(Native Method Stack):主要用于JNI中的原生代码,平时很少涉及。
而Java的使用的是堆内存,java堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,“垃圾回收”也是主要是和堆内存(Heap)有关。
垃圾回收的概念就是JAVA虚拟机(JVM)回收那些不再被引用的对象内存的过程。一般我们认为正在被引用的对象状态为“alive”,而没有被应用或者取不到引用属性的对象状态为“dead”。垃圾回收是一个释放处于”dead”状态的对象的内存的过程。而垃圾回收的规则和算法被动态的作用于应用运行当中,自动回收。
JVM的垃圾回收器采用的是一种分代(generational )回收策略,用较高的频率对年轻的对象(young generation)进行扫描和回收,这种叫做minor collection,而对老对象(old generation)的检查回收频率要低很多,称为major collection。这样就不需要每次GC都将内存中所有对象都检查一遍,这种策略有利于实时观察和回收。
(Sun JVM 1.3 有两种最基本的内存收集方式:一种称为copying或scavenge,将所有仍然生存的对象搬到另外一块内存后,整块内存就可回收。这种方法有效率,但需要有一定的空闲内存,拷贝也有开销。这种方法用于minor collection。另外一种称为mark-compact,将活着的对象标记出来,然后搬迁到一起连成大块的内存,其他内存就可以回收了。这种方法不需要占用额外的空间,但速度相对慢一些。这种方法用于major collection. )
一些对象被创建出来只是拥有短暂的生命周期,比如 iterators 和本地变量。
另外一些对象被创建是拥有很长的生命周期,比如 高持久化对象等。
垃圾回收器的分代策略是把内存区划分为几个代,然后为每个代分配一到多个内存区块。当其中一个代用完了分配给他的内存后,JVM会在分配的内存区内执行一个局部的GC(也可以叫minor collection)操作,为了回收处于“dead”状态的对象所占用的内存。局部GC通常要不Full GC要快很多。
JVM定义了两个代,年轻代(yong generation)(有时称为“nursery”托儿所)和老年代(old generation)。年轻代包括 “Eden space(伊甸园)”和两个“survivor spaces”。 虚拟内存初始化的时候会把所有对象都分配到 Eden space,并且大部分对象也会在该区域被释放。 当进行 minor GC的时候,VM会把剩下的没有释放的对象从Eden space移动到其中一个survivor spaces当中。 此外,VM也会把那些长期存活在survivor spaces 里的对象移动到 老生代的“tenured” space中。当 tenured generation 被填满后,就会产生Full GC,Full GC会相对比较慢因为回收的内容包括了所有的 live状态的对象。pemanet generation这个代包括了所有java虚拟机自身使用的相对比较稳定的数据对象,比如类和对象方法等。
关于代的划分,可以从下图中获得一个概况:
如果垃圾回收器影响了系统的性能,或者成为系统的瓶颈,你可以通过自定义各个代的大小来优化它的性能。使用JConsole,可以方便的查看到当前应用所配置的垃圾回收器的各个参数。想要获得更详细的参数,可以参考以下调优介绍:
Tuning Garbage collection with the 5.0 HotSpot VM
http://java.sun.com/docs/hotspot/gc/index.html
最后,总结一下各区内存:
Eden Space (heap): 内存最初从这个线程池分配给大部分对象。
Survivor Space (heap):用于保存在eden space内存池中经过垃圾回收后没有被回收的对象。
Tenured Generation (heap):用于保持已经在 survivor space内存池中存在了一段时间的对象。
Permanent Generation (non-heap): 保存虚拟机自己的静态(refective)数据,例如类(class)和方法(method)对象。Java虚拟机共享这些类数据。这个区域被分割为只读的和只写的,
Code Cache (non-heap):HotSpot Java虚拟机包括一个用于编译和保存本地代码(native code)的内存,叫做“代码缓存区”(code cache)
第三部分 监控(工具发现问题)
谈到内存监控工具,JConsole是必须要介绍的,它是一个用JAVA写的GUI程序,用来监控VM,并可监控远程的VM,易用且功能强大。具体可监控JAVA内存、JAVA CPU使用率、线程执行情况、加载类概况等,Jconsole需要在JVM参数中配置端口才能使用。
由于是GUI程序,界面可视化,这里就不做详细介绍,
具体帮助支持文档请参阅性能测试JConsole使用方法总结:
http://www.taobao.ali.com/chanpin/km/test/DocLib/性能测试辅助工具-JConsole的使用方法.aspx
或者参考SUN官网的技术文档:
http://Java.sun.com/j2se/1.5.0/docs/guide/management/jconsole.html
http://Java.sun.com/javase/6/docs/technotes/tools/share/jconsole.html
在实际测试某一个项目时,内存出现泄露现象。起初在性能测试的1个小时中,并不明显,而在稳定性测试的时候才发现,应用的HSF调用在经过几个小时运行后,就出现性能明显下降的情况。在服务日志中报大量HSF超时,但所调用系统没有任何超时日志,并且压力应用的load都很低。经过查看日志后,认为应用可能存在内存泄漏。通过jconsole 以及 jmap 工具进行分析发现,确实存在内存泄漏问题,其中PS Old Gen最终达到占用 100%的占用。如图所示:
从上图可以看到,虽然每次Full GC,JVM内存会有部分回收,但回收并不彻底,不可回收的内存对象会越来越多,这样便会出现以上的一个趋势。在Full GC无法回收的对象越来越多时,最终已使用内存达到系统分配的内存最大值,系统最后无内存可分配,最终down机。
第四部分 分析
经过开发和架构师对应用的分析,查看此时内存队列,看哪个对象占用数据最多,再利用jmap命令,对线程数据分析,如下所示:
num #instances #bytes class name
———————————————-
1: 9248056 665860032 com.taobao.matrix.mc.domain.**
2: 9248031 295936992 com.taobao.matrix.**
3: 9248068 147969088 java.util.**
4: 1542111 37010664 java.util.Date
前三个instances不断增加,指代的是同一个代码逻辑,异步分发的问题,堵塞消息,回收多次都无法回收成功。导致内存溢出。
此外,对应用的性能单独做了压测,他的性能只能支撑到一半左右,故发送消息的TPS,应用肯定无法处理过来,导致消息堆积,而JAVA垃圾回收期认为这些都是有用的对象,导致内存堆积,直至系统崩溃。
调优方法
由于具体调优方法涉及到应用的配置信息,故在此暂不列出,可以参考性能测试小组发布的《性能测试调优宝典》
第四部分 总结
内存溢出主要是由于代码编写时对某些方法、类应用不合理,或者没有预估到临时对象会占用很大内存量,或者把过多的数据放入JVM缓存,或者性能压力大导致消息堆积而占用内存,以至于在性能测试时,生成庞大数量的临时对象,GC时没有做出有效回收甚至根本就不能回收,造成内存空间不足,内存溢出。
如果编码之前,对内存使用量进行预估,对放在内存中的数据进行评估,保证有用的信息尽快释放,无用的信息能够被GC回收,这样在一定程度上是可以避免内存溢出问题的。
发表评论
-
使用 JMeter 完成常用的压力测试
2011-07-14 00:04 1040讲到测试,人们脑海中首先浮现的就是针对软件正确性的测试,即 ... -
解密淘宝网的开源架构
2010-10-22 22:10 956淘宝网,是一个在线商品数量突破一亿,日均成交额超过两亿元人 ... -
Google(谷歌)正在构造可怕的帝国
2010-06-22 21:24 974今天看到新浪转载《中国企业家》的一篇文章“百度VS谷歌:优 ... -
百度VS谷歌:优秀与伟大之别
2010-06-22 21:15 781《中国企业家》杂志 百度与Google之间的 ... -
分析称企业IT部门重要性降低:从业人员应转型
2010-06-22 20:59 791导读:美国IT网站Computerworld今天撰文称,随 ... -
火车站信号自动语音播报系统的设计
2010-06-19 19:33 2076在现代工业控制过程中,广泛应用了工作状态和故障状态报警装置,通 ... -
Ping总是丢包的原因,故障排除思路,解决方法
2010-05-27 21:09 3080ping 丢包现象的发生非 ... -
Google:平台化努力
2010-05-26 20:19 846作为门的 Google 从斯坦福 2 位大学生的宿舍作品 ... -
2010年谷歌创新项目盘点
2010-05-25 12:53 9561、Chrome在线应用商店 Chrome Web Stor ... -
想创业的朋友可以看看这几句话。
2010-05-22 14:52 799一个领导人要: 生命取向要高 生命体 ... -
WebSphere Message Broker RouteToLabel
2010-05-20 13:53 840http://publib.boulder.ibm.com/i ... -
李开复:移动互联网在未来的市场和需求
2010-04-05 01:33 836今天我讲一下移动互联 ... -
分享一个壁纸网站,给我这些程序员哥们的眼睛放松放松。
2010-03-19 07:28 2007http://www.vistaback.com/ -
百度产品经理探秘:需求把握和正确决策
2010-01-13 13:22 793编者按:国内互联网公司里,百度的产品一向为人称道。尤其是其搜索 ... -
如何搭建完整的网站架构并设计出一个好站
2009-12-25 12:23 849如何搭建完整的网站架构并设计出一个好站 http://www ... -
《怎样成为优秀的软件架构师》解析 (好文转载)
2009-12-24 22:19 847《怎样成为优秀的软件 ... -
IE浏览器下同一网页多图片显示的瓶颈与优化
2009-12-24 21:36 867Internet Explorer 浏览器在同一时刻只能从同一 ... -
一个项目经理眼中的《2012》
2009-12-16 21:46 722《2012》放映有些时间了,它引起了人们对人性本身的思索。作为 ... -
Design IT. (8),一匹“更快的马”
2009-12-05 21:56 865Design IT. (8),一匹“更快的马” 这是《D ... -
应用程序架构指南 第一部分 第一章 应用程序架构基础
2009-11-09 20:51 1067软件架构基本概念 软件架构通常被描述为组织或系统的结构, ...
相关推荐
刚刚做完了一个项目的性能测试,“有幸”也遇到了内存泄露的案例,所以在此和大家分享一下。主要从以下几部分来说明,关于内存和内存泄露、溢出的概念,区分内存泄露和内存溢出;内存的区域划分,了解GC回收机制;...
性能测试总结之内存泄露和内存溢出[1]软件测试刚刚做完了一个项目的性能测试,“有幸”也遇到了内存泄露的案例,所以在此和大家分享一下。主要从以下几部分来说明,关于内存和内存泄露、溢出的概念,区分内存泄露和...
- 在大型项目中,进行性能测试和压力测试,发现并修复潜在的内存问题。 - 使用适当的JVM监控工具,实时监控JVM的内存使用情况。 总之,Java内存溢出是复杂的问题,需要结合程序设计、JVM参数配置、垃圾收集机制和...
在Android平台上,显示大型GIF图像可能会导致内存溢出(Memory Overflow)问题,因为GIF是一种动画格式,它包含多帧连续的图像,如果直接加载到内存中,会占用大量资源。为了解决这个问题,我们可以采用一些技术策略...
3. **掌握虚拟机栈和本地方法栈内存溢出异常的测试**:探究如何通过递归调用或其他手段导致栈深度超出限制,触发`StackOverflowError`异常;同时,尝试通过增加线程数量的方式模拟栈内存不足的情况,从而引发`...
### Axis2_1.4.1客户端内存溢出...综上所述,通过以上实验步骤,我们不仅能够复现Axis2_1.4.1客户端的内存溢出问题,还能深入理解Web服务开发中潜在的性能挑战及应对策略,这对于提升软件质量和稳定性具有重要意义。
标题中的“[微软工具][内存溢出] LeakDiag & LDGrapher & LeakDiagAutoLog”提及了三个关键工具,它们都是针对内存管理问题的解决方案,特别是针对内存泄漏的检测。在软件开发中,内存泄漏是一个常见的问题,它发生...
内存溢出问题(Out of Memory Error,OOME)在高负载或长时间运行的环境中常见,通常是由于内存分配不当或者垃圾回收机制失效导致的。解决Tomcat内存溢出的常见策略包括: 1. 调整JVM参数:增加堆大小(-Xms和-Xmx...
本文主要从应用的角度来解决中间件应用服务器的内存泄露问题,以提高系统的稳定性和性能。文章通过对某个大型项目的案例分析,介绍了如何使用 JProfiler 工具来诊断内存泄露问题,并提供了解决方法。 一、问题描述 ...
在开发Android应用时,尤其是创建图像画廊或者类似功能时,加载大量图片常常会导致内存溢出(Out Of Memory,简称OOM)。这是因为Android系统为每...在实际开发中,应根据项目需求和性能测试结果选择最适合的优化策略。
1. **确定测试目标**:根据项目需求和业务目标来确定性能测试的具体目标。 2. **设计测试场景**:基于用户行为和系统架构设计出符合实际情况的测试用例。 3. **构建测试环境**:搭建与生产环境相似的测试环境,包括...
通过理解Android内存管理机制,掌握上述防止内存溢出的策略,并结合实际项目中的源码分析,开发者可以有效地优化应用内存使用,提升应用的稳定性和性能。定期进行内存压力测试和代码审查,也能及时发现并修复潜在的...
drool 是一个开源项目,专注于自动内存泄漏检测和分析。在软件开发中,尤其是Java应用程序,内存泄漏是一个常见的问题,可能导致系统性能下降,甚至服务崩溃。drool 提供了一种智能解决方案,帮助开发者及时发现并...
dio_read函数是PHP扩展dio(Device Independent I/O)中的一个重要函数,用于从设备进行非阻塞的低级读取操作...在实际项目中,定期更新和维护依赖库,以获取最新的安全补丁和性能优化,是保障系统稳定运行的重要环节。
BoundsChecker通过静态分析和动态运行时检查来检测内存泄露、缓冲区溢出、未初始化的变量等错误。静态分析在编译时进行,可以找出潜在的代码问题,而动态运行时检查则在程序运行时监控内存分配和释放,能够定位到...
1. 内存溢出的迹象:项目中Golang程序在运行后内存占用急剧上升,从最初运行的十几兆字节,增长到十几个吉字节。这表明程序存在内存泄漏,特别是当流量减少时,内存占用也没有明显降低,内存状态呈现不健康的曲线,...
- 定期分析内存使用情况,避免内存溢出。 - 优化代码,减少不必要的对象创建和引用。 通过深入理解这些概念并运用到实际项目中,开发者可以有效地提升Java应用的性能和稳定性。提供的代码示例将帮助你实践这些...
在当前IT技术发展的浪潮中,Java虚拟机(JVM)作为应用最广泛的平台之一,其性能调优显得尤为...对于软件测试、开发及运维人员而言,掌握这些性能调优的知识和技能,是提高工作效率、保证项目成功不可或缺的一部分。