`
xuexing
  • 浏览: 24032 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Java内存泄漏阐述与解决方案(转)

阅读更多
Java内存泄漏是每个Java程序员都市遇到的问题,程序在当地运行完全合理,可是布署到远端就会出现内存无局限的增长,最后体系瘫痪,那么怎样最快最好的检测程序的安稳性,避免体系崩盘,作者用自已的亲身体验与各位网友分享解决这些问题的办法。

  作为Internet最盛行的编程语言之一,Java现正十分盛行。我们的网络运用程序就紧要选用Java语言开发,大致上分为客户端、服务器和数据库三个条理。在投入测试过程中,我们发现有一个程序模块体系内存和CPU资源耗损急剧增加,持续增长到出现 java.lang.OutOfMemoryError为止。经过阐述Java内存泄漏是破坏体系的紧要因素。这里与大众分享我们在开发过程中遇到的 Java内存泄漏的检测和办解析决过程.

  一.Java是怎样管理内存

  为了研判Java中是否有内存败露,我们第一必需了解Java是怎样管理内存的。Java的内存管理即是对象的分派和释放问题。在Java中,内存的分派是由程序达成的,而内存的释放是由垃圾采集器达成的,程序员不需要经过调用函数来释放内存,但它只能回收无用而且不再被其余对象引用的那些对象所占用的空间。

  Java的内存垃圾回收机制是从程序的紧要运行对象开始检验引用链,当遍历一遍后发现没有被引用的孤立对象就作为垃圾回收。GC为了能够正确释放对象,必需监控每一个对象的运行状态,包罗对象的申请、引用、被引用、赋值等,GC都需要进行监控。看管对象状态是为了越发准确地、及时地释放对象,而释放对象的基本原则即是该对象不再被引用。

  在Java中,这些无用的对象都由GC负责回收,所以程序员不需要思考这部分的内存败露。虽然,我们有几个函数可以访问GC,比如运行GC的函数System.gc,可是依据Java语言规范定义,该函数不担保JVM的垃圾采集器肯定会执行。因为差异的JVM实现者可能利用差异的算法管理GC。通常GC的线程的优先级别较低。JVM调用GC的攻略也有许多种,有的是内存利用抵达肯定程度时,GC才开始工作,也有定时执行的,有的是平坦执行GC,有的是间断式执行GC。但通常来说,我们不需要关怀这些。

  二.什么是Java中的内存败露

  导致内存泄漏紧要的原因是,先前申请了内存空间而遗忘了释放。假如程序中存在对无用对象的引用,那么这些对象就会驻留内存,耗损内存,因为无法让垃圾回收器GC验证这些对象是否不再需要。假如存在对象的引用,这个对象就被定义为"有效的活动",同时不会被释放。要确定对象所占内存将被回收,我们就要务必确认该对象不再会被利用。范例的制法即是把对象数据会员设为null或者从集合中移除该对象。但当小面积变量不需要时,不需明显的设为null,因为一个办法执行完结时,这些引用会自动被清理。

  在Java中,内存泄漏即是存在一些被分派的对象,这些对象有下面两个特点,第一,这些对象是有被引用的,即在有向树形图中,存在树枝通路可以与其相连;第二,这些对象是无用的,即程序往后不会再利用这些对象。假如对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,不过它却占用内存。

  这里引用一个常看到的例子,鄙人面的代码中,循环申请 Object对象,并将所申请的对象插进一个Vector中,假如仅仅释放对象自身,但因为Vector如故引用该对象,所以这个对象对GC来说是不行回收的。所以,假如对象参与到Vector后,还必需从Vector中删除,最容易的办法即是将Vector对象设置为null。

  Vectorv=newVector;for......{ Objecto=newObject; v.add; o=null;}//这时,全面的Object对象都没有被释放,因为变量v引用这些对象。

  事实上这些对象已经是无用的,但还被引用,GC就无能为力了,这一点是导致内存泄漏最首要的原因。再引用另一个例子来阐明Java的内存泄漏。假设有一个日志类Logger,其供应一个静态的log,任何其余类都可以调用Logger.Log来将message的内容记录到体系的日志文件中。

  Logger类有一个类型为HashMap的静态变量temp,每次在执行log的时刻,都第一将message的值写入temp中,在退出之前再从 temp中将以当前线程和当前时间为键的条目删除。注意,这里当前时间是继续变动的,所以log在退出之前执行删除条目标驾驭并不能删除执行之初写入的条目。这样,任何一个作为参数传给log的字符串最终由于被Logger的静态变量temp引用,而无法获得回收,这种对象维持即是我们所说的Java内存泄漏。总的来说,内存管理中的内存泄漏产生的紧要原因:保剩下来却永远不再利用的对象引用。

  三.几种范例的内存泄漏

  我们知道了在Java中切实会存在内存泄漏,那么就让我们看一看几种范例的泄漏,并找出他们产生的原因和解决办法。

  3.1全局集合

  在大型运用程序中存在各种各样的全局数据货仓是很普遍的,比如一个JNDI-tree或者一个sessiontable。在这些状况下,必需注意管理储存库的大小。必需有某种机制从储存库中移除不再需要的数据。

  通常有许多差异的解决格式,个中最经常用的是一种周期运行的根除功课。这个功课会验证货仓中的数据然后根除完全不需要的数据。

  另一种管理储存库的办法是利用反向链接计数。然后集合负责统计集合中每个进口的反向链接的数目。这要求反向链接告知集合何时会退出进口。当反向链接数目为零时,该元素就可以从集合中移除了。

  3.2缓存

  缓存一种用来快捷寻找已经执行过的驾驭结果的数据结构。所以,假如一个驾驭执行需要对比多的资源并会多次被利用,通常制法是把经常用的输入数据的驾驭结果进行缓存,以便鄙人次调用该驾驭时利用缓存的数据。缓存通常都是以动态要领实现的,假如缓存设置不正确而多量利用缓存的话则会出现内存溢出的后果,所以需要将所利用的内存容量与搜索数据的速度加以均衡。

  经常用的解决途径是利用java.lang.ref.SoftReference类坚持将对象插进缓存。这个办法可以担保当虚拟机用完内存或者需要更多堆的时刻,可以释放这些对象的引用。

  3.3类装载器

  Java类装载器的利用为内存泄漏供应了许多可乘之机。一般来说类装载器都具备混杂结构,因为类装载器不仅仅是只与"常规"对象引用有关,同时也和对象内部的引用有关。比如数据变量,办法和各种类。这意味着只要存在对数据变量,办法,各种类和对象的类装载器,那么类装载器将驻留在JVM中。既然类装载器可以同许多的类关连,同时也可以和静态数据变量关连,那么相当多的内存就可能产生泄漏。

  四.怎样检测和办理内存泄漏

  怎样寻找引起内存泄漏的原因一般有两个步骤:第一是部署有经验的程序员对代码进行走查和阐述,找出内存泄漏产生的位置;第二是利用专门的内存泄漏测试工具进行测试。

  第一个步骤在代码走查的工作中,可以部署对体系业务和开发语言工具对比熟悉的开发人员对运用的代码进行了交叉走查,尽量找出代码中存在的数据库联接注明和结果集未关闭、代码冗余等故障代码。

  第二个步骤即是检测Java的内存泄漏。在这里我们通常利用一些工具来检验Java程序的内存泄漏问题。市场上已有几种专业检验Java内存泄漏的工具,它们的基本工作原理大同小异,都是经过监测Java程序运行时,全面对象的申请、释放等动作,将内存管理的全面资料进行统计、阐述、可视化。开发人员将依据这些资料研判程序是否有内存泄漏问题。这些工具包罗 OptimizeitProfiler,JProbeProfiler,JinSight,Rational公司的Purify等。

  4.1检测内存泄漏的存在

  这里我们将容易介绍我们在利用Optimizeit检验的过程。通常在知道产生内存泄漏之后,第一步是要弄清楚泄漏了什么数据和哪个类的对象引起了泄漏。

  一般说来,一个合理的体系在其运行安稳后其内存的占用量是基本安稳的,不应当是无局限的增长的。同样,对任何一个类的对象的利用个数也有一个相对安稳的上限,不应当是持续增长的。依据这样的基本假设,我们持续地巡视体系运行时利用的内存的大小和各实例的个数,假如内存的大小持续地增长,则阐明体系存在内存泄漏,假如特定类的实例对象个数随时间而增长(即是所谓的“增长率”),则阐明这个类的实例可能存在泄漏状况。

  另一是通常产生内存泄漏的第一个迹象是:在运用程序中出现了OutOfMemoryError。在这种状况下,需要利用一些付出较低的工具来监控和寻找内存泄漏。虽然 OutOfMemoryError也有可能运用程序切实正在利用这么多的内存;对于这种状况则可以增加JVM可用的堆的数量,或者对运用程序进行某种更正,使它利用较少的内存。

  可是,在许多状况下,OutOfMemoryError都是内存泄漏的信号。一种查明办法是不间断地监控GC的活动,确定内存利用量是否随着时间增加。假如切实如此,就可能产生了内存泄漏。

  4.2办理内存泄漏的办法

  一旦知道切实产生了内存泄漏,就需要更专业的工具来查明为何会产生泄漏。JVM自己是不会告知您的。这些专业工具从JVM获得内存体系资料的办法基本上有两种:JVMTI和字节码技艺。Java虚拟机工具接口及其前身Java虚拟机看管程序接口是外部工具与JVM通信并从JVM采集资料的轨范化接口。字节码技艺是指利用探测器办理字节码以获得工具所需的资料的技艺。

  Optimizeit是Borland公司的产物,紧要用于帮助对软件体系进行代码优化和故障诊断,个中的OptimizeitProfiler紧要用于内存泄漏的阐述。Profiler的堆视图即是用来巡视体系运行利用的内存大小和各个类的实例分派的个数的。

  第一,Profiler会进行态势阐述,找出是哪个类的对象在泄漏。体系运行长时间后可以获得四个内存快照。对这四个内存快照进行综合阐述,假如每一次快照的内存利用都比上一次有增长,可以认定体系存在内存泄漏,找出在四个快照中实例个数都维持增长的类,这些类可以初步被认定为存在泄漏。经过数据采集和初步阐述,可以得出初步结论:体系是否存在内存泄漏和哪些对象存在泄漏。

  接下来,看看有哪些其他的类与泄漏的类的对象相干联。前面已经谈到Java中的内存泄漏即是无用的对象维持,容易地说即是因为编码的过错导致了一条原本不应当存在的引用链的存在,所以内存泄漏阐述的事务即是找出这条多余的引用链,并找到其变成的原因。查看对象分派到哪里是很有用的。同时只知道它们怎样与其他对象相干联(即哪些对象引用了它们)是不足的,关于它们在何处树立的资料也很有用。

  最后,进一步研讨单个对象,看看它们是怎样互相干联的。借助于Profiler工具,运用程序中的代码可以在分派时进行动态添加,以树立栈房跟踪。也有可以对体系中全面对象分派进行动态的栈房跟踪。这些栈房跟踪可以在工具中进行累积和阐述。对每个被泄漏的实例对象,必定存在一条从某个牵引对象出发抵达该对象的引用链。处于栈房空间的牵引对象在被从栈中弹出后就遗失其牵引的本领,变为非牵引对象。所以,在长时间的运行后,被败露的对象基本上都是被作为类的静态变量的牵引对象牵引。

  总而言之,Java虽然有自动回收管理内存的功能,但内存泄漏也是不容忽视,它频频是破坏体系安稳性的首要因素。
分享到:
评论

相关推荐

    Java系统中内存泄漏测试方法的研究

    总结,Java系统中的内存泄漏测试和分析涉及多个方面,包括理解内存管理机制、识别泄漏原因、使用专业工具以及制定有效的解决方案。开发者应当养成良好的编程习惯,注重代码质量,以减少内存泄漏的发生。同时,利用...

    JAVA内存调优白皮书(IBM)

    9. **内存溢出问题**:解释不同类型的内存溢出错误,如Heap OutOfMemoryError、PermGen Space OutOfMemoryError(Java 8以后为Metaspace OutOfMemoryError)的产生原因和解决方案。 10. **实战案例**:通过具体的...

    最全 java23种设计模式 Debug模式+内存分析

    设计模式是面向对象编程中的一种通用解决方案,它为软件开发中遇到的常见问题提供了模板式的解决方法。Java作为一门成熟的面向对象语言,广泛应用于企业级应用的开发中,因此掌握其设计模式对于提高代码质量和可维护...

    Java性能优化英文版

    通过真实的性能问题案例,展示了如何诊断问题、定位性能瓶颈,并提供解决方案,使读者能够将理论知识应用于实际工作。 通过阅读《Java Performance》英文版,不仅可以提升你的Java性能优化技能,还能锻炼英语阅读...

    java调用dll详解.rar

    5. **内存管理**:Java的垃圾回收机制与C/C++的内存管理不同,使用JNI调用DLL时,要小心内存分配和释放,避免内存泄漏。 6. **错误处理**:DLL调用可能失败,因此在Java中调用native方法后,需要检查返回值并处理...

    Thinking in java 电子书

    11. **垃圾回收与内存管理**:Java的自动内存管理是其一大特点,书中介绍了垃圾回收的工作原理和优化策略,帮助开发者避免内存泄漏等问题。 12. **设计模式**:书中还讨论了多种设计模式,如工厂模式、单例模式、...

    java面试——深圳-商汤科技-Java高级.zip

    5. **设计模式**:设计模式是软件开发的通用解决方案,常见的有单例模式、工厂模式、观察者模式、装饰器模式等23种GOF设计模式。能够灵活运用设计模式解决实际问题,是衡量开发者经验与能力的重要标准。 6. **反射...

    Thinking in java 3 中英双语

    10. **垃圾收集与内存管理**:Java的自动内存管理是其魅力之一,书中会讨论如何理解内存分配、垃圾收集的工作原理以及如何避免内存泄漏。 11. **设计模式**:书中还会介绍一些常见的设计模式,如工厂模式、单例模式...

    thinking in java 第四版

    接着,书中详细阐述了Java的内存管理,包括自动内存管理(垃圾回收机制)和内存区域,如堆、栈、方法区等。了解这些内容对于避免内存泄漏和提高程序性能至关重要。此外,书中还介绍了如何使用Java集合框架,如...

    Java虚拟机(第二版)

    还会讨论死锁、活锁和饥饿等并发问题及其解决方案。 还有,JVM的编译优化,如HotSpot JVM的动态编译技术,包括如何识别热点代码并进行即时编译,以及如何使用逃逸分析等优化技术。这些内容可以帮助开发者理解JVM...

    java课程设计报告

    这个报告旨在详细阐述设计过程、所用技术、遇到的问题以及解决方案,旨在全面展示学生的编程技能和问题解决能力。 一、Java语言基础 Java是一种广泛使用的高级编程语言,由Sun Microsystems(现为Oracle公司)于...

    2019Java高级面试专题

    4. 分布式事务:学习分布式事务的解决方案,如2PC、补偿事务TCC、最终一致性等。 5. 容器化与Docker:了解Docker容器技术,学习Dockerfile编写,熟练运用Docker Compose进行服务编排。 三、数据库原理 1. 数据库...

    中国娱乐网站解决方案 网站建设方案 网站解决方案

    在中国娱乐网站的解决方案中,网站建设方案是至关重要的环节,它涉及到多个方面,包括技术选型、用户体验设计、内容管理、安全防护以及数据分析等。以下是对这些关键知识点的详细阐述: 一、技术选型: 1. 后端开发...

    java面试题高级, 对底层高并发深入理解

    在Java面试中,对于高级职位,面试官通常会考察应聘者对Java语言的深入理解和在高并发环境下的...在面试中,除了理论知识,还要能够结合实际项目经验来阐述和解释问题,展示自己在高并发场景下的解决方案和实践经验。

    java使用HttpClient通过url下载文件到本地

    在Java编程环境中,HttpClient库是Apache HTTP Components项目的一部分,它为开发者提供了强大的HTTP客户端功能,可以...通过理解HttpClient的工作原理和提供的API,开发者可以构建出稳定、高效的文件下载解决方案。

    java核心技术

    《Java核心技术》作为...它不仅仅停留在语法层面,而是深入到设计理念、最佳实践和常见问题解决方案,为读者提供了一个全面、系统的Java知识体系。无论是初学者还是有经验的开发者,都能从中获得新的启示和技能提升。

    java视频上传,转码,截图,播放实现

    这个项目似乎提供了一个完整的解决方案,涵盖了这些功能,并且整合了数据库管理。下面将详细阐述这些关键知识点。 1. **视频上传**:在Java中,视频上传通常涉及HTTP上传或者FTP服务。使用Servlet或Spring MVC可以...

    Java语言程序设计-进阶篇(原书第10版 中英文)

    13. Web应用开发:Java EE(Enterprise Edition)为企业级应用提供了一整套解决方案,包括Servlet、JSP、EJB等技术,读者将了解到如何构建动态网站和企业级应用。 通过阅读《Java语言程序设计-进阶篇》,读者不仅...

    一个牛人给java初学者的建议

    Java ME(Java Micro Edition)为嵌入式设备和物联网提供了轻量级的解决方案,使得Java可以在资源受限的设备上运行,实现智能互联。 ### Java学习路径建议 对于Java初学者而言,掌握Java语言的基础语法只是第一步...

Global site tag (gtag.js) - Google Analytics