??xml version="1.0" encoding="utf-8" standalone="yes"?>天海翼亚洲一区二区三区,国产精品一区二区三区av麻,欧美日韩精品久久久http://www.aygfsteel.com/kellyyu82/category/39168.htmlzh-cnTue, 21 Apr 2009 06:49:26 GMTTue, 21 Apr 2009 06:49:26 GMT60解决Java内存泄漏 http://www.aygfsteel.com/kellyyu82/articles/240541.html老鱼吃猫老鱼吃猫Fri, 14 Nov 2008 07:19:00 GMThttp://www.aygfsteel.com/kellyyu82/articles/240541.htmlhttp://www.aygfsteel.com/kellyyu82/comments/240541.htmlhttp://www.aygfsteel.com/kellyyu82/articles/240541.html#Feedback0http://www.aygfsteel.com/kellyyu82/comments/commentRss/240541.htmlhttp://www.aygfsteel.com/kellyyu82/services/trackbacks/240541.html
解决Java内存泄漏

Java内存泄漏是每个JavaE序员都会遇到的问题,E序在本地运行一切正?可是布v到远端就会出现内存无限制的增?最后系l瘫?那么如何最快最好的程序的E_?防止pȝ崩盘,作者用自已的亲w经历与各位分n解决q些问题的办?
 
作ؓInternet最行的编E语a之一,Java现正非常行.我们的网l应用程序就主要采用Java语言开?大体上分为客L、服务器?a onclick="javascript:tagshow(event, '%CA%FD%BE%DD%BF%E2');" href="javascript:;" target="_self">数据?/strong>三个层次.在进?a onclick="javascript:tagshow(event, '%B2%E2%CA%D4');" href="javascript:;" target="_self">q程?我们发现有一个程序模块系l内存和CPU资源消耗急剧增加,持箋增长到出现java.lang.OutOfMemoryError为止.l过分析Java内存泄漏是破坏系l的主要因素.q里与大家分享我们在开发过E中遇到的Java内存泄漏的检和处理解决q程.

一. Java是如何管理内?

Z判断Java中是否有内存泄露,我们首先必须了解Java是如何管理内存的.Java的内存管理就是对象的分配和释N?在Java?内存的分配是q序完成的,而内存的释放是由垃圾攉?Garbage Collection,GC)完成?E序员不需要通过调用函数来释攑ֆ?但它只能回收无用q且不再?a onclick="javascript:tagshow(event, '%C6%E4%CB%FC');" href="javascript:;" target="_self">其它对象引用的那些对象所占用的空?

Java的内存垃圑֛收机制是从程序的主要q行对象开始检查引用链,当遍历一遍后发现没有被引用的孤立对象׃为垃圑֛?GCZ能够正确释放对象,必须监控每一个对象的q行状?包括对象的申诗引用、被引用、赋值等,GC都需要进行监?监视对象状态是Z更加准确地、及时地释放对象,而释攑֯象的Ҏ原则是该对象不再被引用.

在Java?q些无用的对象都由GC负责回收,因此E序员不需要考虑q部分的内存泄露.虽然,我们有几个函数可以访问GC,例如q行GC的函数System.gc(),但是ҎJava语言规范定义,该函C保证JVM的垃圾收集器一定会执行.因ؓ不同的JVM实现者可能用不同的法理GC.通常GC的线E的优先U别较低.JVM调用GC的策略也有很多种,有的是内存用到达一定程度时,GC才开?a onclick="javascript:tagshow(event, '%B9%A4%D7%F7');" href="javascript:;" target="_self">工作,也有定时执行?有的是^~执行GC,有的是中断式执行GC.但通常来说,我们不需要关心这?

? 什么是Java中的内存泄露

D内存泄漏主要的原因是,先前甌了内存空间而忘C释放.如果E序中存在对无用对象的引?那么q些对象׃ȝ内存,消耗内?因ؓ无法让垃圑֛收器GC验证q些对象是否不再需?如果存在对象的引?q个对象p定义?有效的活?,同时不会被释?要确定对象所占内存将被回?我们p务必认该对象不再会被?典型的做法就是把对象数据成员设ؓnull或者从集合中移除该对象.但当局部变量不需要时,不需明显的设为null,因ؓ一个方法执行完毕时,q些引用会自动被清理.

在Java?内存泄漏是存在一些被分配的对?q些对象有下面两个特?首先,q些对象是有被引用的,卛_有向树Ş图中,存在树枝通\可以与其相连Q其?q些对象是无用的,即程序以后不会再使用q些对象.如果对象满q两个条?q些对象可以判定ؓJava中的内存泄漏,q些对象不会被GC所回收,然而它却占用内?

q里引用一个常看到的例?在下面的代码?循环甌Object对象,q将所甌的对象放入一个Vector?如果仅仅释放对象本n,但因为Vector仍然引用该对?所以这个对象对GC来说是不可回收的.因此,如果对象加入到Vector?q必MVector中删?最单的Ҏ是Vector对象讄为null.实际上这些对象已l是无用?但还被引?GC无能ؓ力了(事实上GC认ؓ它还有用),q一ҎD内存泄漏最重要的原? 再引用另一个例子来说明Java的内存泄?假设有一?a onclick="javascript:tagshow(event, '%C8%D5%D6%BE');" href="javascript:;" target="_self">日志cLogger,其提供一个静态的log(String msg),M其它c都可以调用Logger.Log(message)来将message的内容记录到pȝ的日志文件中.

LoggercL一个类型ؓHashMap的静态变量temp,每次在执行log(message)的时?都首先将message的值写入temp?以当前线E?当前旉为键),在退Z前再从temp中将以当前线E和当前旉为键的条目删?注意,q里当前旉是不断变化的,所以log在退Z前执行删除条目的操作q不能删除执行之初写入的条目.q样,M一个作为参Cllog的字W串最l由于被Logger的静态变量temp引用,而无法得到回?q种对象保持是我们所说的Java内存泄漏. ȝ来说,内存理中的内存泄漏产生的主要原因:保留下来却永q不再用的对象引用.

? 几种典型的内存泄?

我们知道了在Java中确实会存在内存泄漏,那么p我们看一看几U典型的泄漏,q找Z们发生的原因和解x?

3.1 全局集合

在大型应用程序中存在各种各样的全局数据仓库是很普遍?比如一个JNDI-tree或者一个session table.在这些情况下,必须注意理储存库的大小.必须有某U机制从储存库中U除不再需要的数据.

通常有很多不同的解决形式,其中最常用的是一U周期运行的清除作业.q个作业会验证仓库中的数据然后清除一切不需要的数据.另一U管理储存库的方法是使用反向链接(referrer)计数.然后集合负责l计集合中每个入口的反向链接的数?q要求反向链接告诉集合何时会退出入?当反向链接数目ؓ零时,该元素就可以从集合中U除?

3.2 ~存
~存一U用来快速查扑ַl执行过的操作结果的数据l构.因此,如果一个操作执行需要比较多的资源ƈ会多ơ被使用,通常做法是把常用的输入数据的操作l果q行~存,以便在下ơ调用该操作时用缓存的数据.~存通常都是以动态方式实现的,如果~存讄不正而大量用缓存的话则会出现内存溢出的后果,因此需要将所使用的内存容量与索数据的速度加以q.

常用的解决途径是用java.lang.ref.SoftReferencecd持将对象攑օ~存.q个Ҏ可以保证当虚拟机用完内存或者需要更多堆的时?可以释放q些对象的引?

3.3 c装载器
Javac装载器的用ؓ内存泄漏提供了许多可乘之?一般来说类装蝲器都h复杂l构,因ؓc装载器不仅仅是只与"常规"对象引用有关,同时也和对象内部的引用有?比如数据变量,Ҏ和各U类.q意味着只要存在Ҏ据变?Ҏ,各种cd对象的类装蝲?那么c装载器驻留在JVM?既然c装载器可以同很多的cd?同时也可以和静态数据变量关?那么相当多的内存可能发生泄?

? 如何和处理内存泄漏

如何查找引v内存泄漏的原因一般有两个步骤:W一是安排有l验的编Eh员对代码q行走查和分?扑և内存泄漏发生的位|?W二是用专门的内存泄漏试工具q行试.

W一个步?在代码走查的工作?可以安排对系l业务和开发语a工具比较熟悉的开发h员对应用的代码进行了交叉走查,量扑և代码中存在的数据库连接声明和l果集未关闭、代码冗余等故障代码.

W二个步?是Java的内存泄?在这里我们通常使用一些工h查JavaE序的内存泄漏问?市场上已有几U专业检查Java内存泄漏的工?它们的基本工作原理大同小?都是通过监测JavaE序q行?所有对象的甌、释攄动作,内存管理的所有信息进行统计、分析、可视化.开发h员将Ҏq些信息判断E序是否有内存泄漏问?q些工具包括Optimizeit Profiler,JProbe Profiler,JinSight , Rational 公司的Purify{?

4.1内存泄漏的存在
q里我们简单介l我们在使用Optimizeit查的q程.通常在知道发生内存泄漏之?W一步是要弄清楚泄漏了什么数据和哪个cȝ对象引v了泄?

一般说?一个正常的pȝ在其q行E_后其内存的占用量是基本稳定的,不应该是无限制的增长?同样,对Q何一个类的对象的使用个数也有一个相对稳定的上限,不应该是持箋增长?Ҏq样的基本假?我们持箋地观察系l运行时使用的内存的大小和各实例的个?如果内存的大持l地增长,则说明系l存在内存泄?如果特定cȝ实例对象个数随时间而增?是所谓的“增长?#8221;),则说明这个类的实例可能存在泄漏情?

另一斚w通常发生内存泄漏的第一个迹象是Q在应用E序中出COutOfMemoryError.在这U情况下,需要用一些开销较低的工h监控和查扑ֆ存泄?虽然OutOfMemoryError也有可能应用E序实正在使用q么多的内存Q对于这U情况则可以增加JVM可用的堆的数?或者对应用E序q行某种更改,使它使用较少的内?

但是,在许多情况下,OutOfMemoryError都是内存泄漏的信?一U查明方法是不间断地监控GC的活?定内存使用量是否随着旉增加.如果实如此,可能发生了内存泄漏.

4.2处理内存泄漏的方?
一旦知道确实发生了内存泄漏,需要更专业的工h查明Z么会发生泄漏.JVM自己是不会告诉您?q些专业工具从JVM获得内存pȝ信息的方法基本上有两U:JVMTI和字节码技?byte code instrumentation).Java虚拟机工h?Java Virtual Machine Tools Interface,JVMTI)及其前nJava虚拟机监视程序接?Java Virtual Machine Profiling Interface,JVMPI)是外部工具与JVM通信q从JVM攉信息的标准化接口.字节码技术是指用探器处理字节码以获得工具所需的信息的技?

Optimizeit是Borland公司的?主要用于协助对Y件系l进行代码优化和故障诊断,其中的Optimizeit Profiler主要用于内存泄漏的分?Profiler的堆视图是用来观察pȝq行使用的内存大和各个cȝ实例分配的个数的.

首先,Profiler会进行趋势分?扑և是哪个类的对象在泄漏.pȝq行长时间后可以得到四个内存快照.对这四个内存快照q行l合分析,如果每一ơ快照的内存使用都比上一ơ有增长,可以认定pȝ存在内存泄漏,扑և在四个快照中实例个数都保持增长的c?q些cd以初步被认定为存在泄?通过数据攉和初步分?可以得出初步l论:pȝ是否存在内存泄漏和哪些对象存在泄?被泄?.

接下?看看有哪?a onclick="javascript:tagshow(event, '%C6%E4%CB%FB');" href="javascript:;" target="_self">其他的类与泄漏的cȝ对象相关?前面已经谈到Java中的内存泄漏是无用的对象保?单地说就是因为编码的错误D了一条本来不应该存在的引用链的存?从而导致了被引用的对象无法释放),因此内存泄漏分析的Q务就是找条多余的引用?q找到其形成的原?查看对象分配到哪里是很有用的.同时只知道它们如何与其他对象相关?卛_些对象引用了它们)是不够的,关于它们在何处创建的信息也很有用.
  
最?q一步研I单个对?看看它们是如何互相关联的.借助于Profiler工具,应用E序中的代码可以在分配时q行动态添?以创建堆栈跟t?也有可以对系l中所有对象分配进行动态的堆栈跟踪.q些堆栈跟踪可以在工具中q行累积和分?Ҏ个被泄漏的实例对?必然存在一条从某个牵引对象出发到达该对象的引用?处于堆栈I间的牵引对象在被从栈中弹出后就失去其牵引的能力,变ؓ非牵引对?因此,在长旉的运行后,被泄露的对象基本上都是被作ؓcȝ静态变量的牵引对象牵引.

总而言? Java虽然有自动回收管理内存的功能,但内存泄漏也是不容忽?它往往是破坏系l稳定性的重要因素.



老鱼吃猫 2008-11-14 15:19 发表评论
]]>
վ֩ģ壺 | | żҿ| | | ɽ| Ѱ| пѷ| | ƽ| | | | | ͡| ˮ| ̩| | ɽ| ɽ| | «| | ӽ| Ȫ| | ˮ| | | ƽ| ͤ| | | | | | | | | ɽ| |