`

Java基础恶补——内存泄露、内存溢出

    博客分类:
  • Java
阅读更多

 --------------------------------------------------------------------------------------------

参考: http://developer.51cto.com/art/200906/129346.htm

--------------------------------------------------------------------------------------------

要点

  • 内存泄露是指程序中间动态分配了内存,但在程序结束时没有释放这部分内存,从而造成那部分内存不可用的情况,重启计算机可以解决,但也有可能再次发生内存泄露,内存泄露和硬件没有关系,它是由软件设计缺陷引起的。 
  • 内存泄漏可以分为4类:

    1) 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

    2) 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。

    3) 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。

    4) 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

  • 内存溢出类型

    1) java.lang.OutOfMemoryError: PermGen space

    PermGen space 的全称是 Permanent Generation space, 是指内存的永久保存区域。这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC不会在主程序运行期对PermGen space进行清理。

     

    JVM由XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;

    JVM由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

     

    该错误常见场合:

    a) 应用中有很多Class,web服务器对JSP进行pre compile时。

    b) Webapp下用了大量的第三方jar, 其大小超过了JVM默认的大小(4M)时。

     

    2) java.lang.OutOfMemoryError: Java heap space

     

    在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。

     

    JVM初始分配的内存由-Xms指定,默认是物理内存的1/64; 

    JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。 

     

    JVM内存的最大值跟操作系统有很大的关系。32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

    注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。 

    该错误常见场合:

    a) Web上传文件时。

    b) 开启大型文件或从数据库中一次取了太多的数据。 

    3) 调优JVM内存解决OutOfMemoryError

     

 

相关问题

1. Q: Java中会存在内存泄漏吗?
   
A:  Java中也存在内存泄露。当被分配的对象可达但已无用(未对作废数据内存单元的引用置null)即会引起。

         如:

Vector v=new Vector(10); 
for (int i=1;i<100; i++) { 
    Object o=new Object(); 
    v.add(o); 
    o=null; 
} 
// 此时,所有的Object对象都没有被释放,因为变量v引用这些对象。 
// 对象加入到Vector后,还必须从Vector中删除,最简单释放方法就是将Vector对象设置为null。 

 

 

2. Q: 内存泄露、溢出的异同? 

     A: 同:都会导致应用程序运行出现问题,性能下降或挂起。

         异:

         1) 内存泄露是导致内存溢出的原因之一;内存泄露积累起来将导致内存溢出。

         2) 内存泄露可以通过完善代码来避免;内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。

        

 

 

3. 如何检测内存泄露?   

 

 

     A: 可以通过一些性能监测分析工具,如 JProfiler、Optimizeit Profiler。

 

4. Q: 如何避免内存泄露、溢出?
     A: 1) 尽早释放无用对象的引用。

          好的办法是使用临时变量的时候,让引用变量在退出活动域后自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。

          2) 程序进行字符串处理时,尽量避免使用String,而应使用StringBuffer。

          因为每一个String对象都会独立占用内存一块区域,如:

 

String str = "aaa"; 
String str2 = "bbb"; 
String str3 = str + str2; 
// 假如执行此次之后str , str2再不被调用,那么它们就会在内存中等待GC回收; 
// 假如程序中存在过多的类似情况就会出现内存错误; 

 

 

         3) 尽量少用静态变量。

         因为静态变量是全局的,GC不会回收。

         4) 避免集中创建对象尤其是大对象,如果可以的话尽量使用流操作。

         JVM会突然需要大量内存,这时会触发GC优化系统内存环境; 一个案例如下: 

 

// 使用jspsmartUpload作文件上传,运行过程中经常出现java.outofMemoryError的错误, 
// 检查之后发现问题:组件里的代码 
m_totalBytes = m_request.getContentLength(); 
m_binArray = new byte[m_totalBytes]; 
// totalBytes这个变量得到的数极大,导致该数组分配了很多内存空间,而且该数组不能及时释放。 
// 解决办法只能换一种更合适的办法,至少是不会引发outofMemoryError的方式解决。 
// 参考:http://bbs.xml.org.cn/blog/more.asp?name=hongrui&id=3747 

 

 

 

        5) 尽量运用对象池技术以提高系统性能。

         生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。

         6) 不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。

         可以适当的使用hashtable,vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃。

         7) 优化配置。

 

 

 

 

 

5. Q: 内存溢出的解决方案? 
     A: 一是从代码层面进行优化完善,尽量避免该情况发生;

         二是调整优化服务器配置: 

         1) 设置-Xms、-Xmx相等;

         2) 设置NewSize、MaxNewSize相等;

         3) 设置Heap size, PermGen space:

             Tomcat 的配置示例:修改 %TOMCAT_HOME%/bin/catalina.bat or catalina.sh

             在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:

 

set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m

 

Java内存模型FAQ

 

 

分享到:
评论

相关推荐

    java内存泄露、溢出检查方法和工具

    本文将深入探讨如何检测和分析Java内存泄露与溢出,并介绍一种常用的工具——Memory Analyzer(MAT)。 首先,理解内存泄露的概念至关重要。在Java中,内存泄露通常发生在对象不再被程序使用但仍然保持在内存中,...

    JAVA内存溢出问题总结

    JAVA内存溢出问题总结 JAVA 内存溢出问题是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用的内存大于虚拟机能提供的最大内存。内存溢出问题可以从容器和程序类两个方面进行排查,容器问题...

    内存泄漏与内存溢出

    在软件开发领域,尤其是涉及到数据库应用的场景下,内存泄漏(Memory Leak)和内存溢出(Out of Memory,简称OOM)是两个常见的问题,它们直接影响到程序的性能、稳定性和可扩展性。以下是对这两个概念及其相关知识...

    JAVA内存溢出

    JAVA内存溢出 JAVA中OutOfMemoryError(内存溢出)的三种情况及解决办法 Java中的OutOfMemoryError(内存溢出)是一种常见的错误,本文将详细介绍OutOfMemoryError的三种情况及其解决方法。 首先,我们需要了解...

    Java加载dll,导致Java进程内存泄露

    标题“Java加载dll,导致Java进程内存泄露”涉及到的是Java平台与本地库(DLL)交互时可能出现的问题。在Java中,通过Java Native Interface (JNI) 可以调用C/C++编写的动态链接库(DLL),实现Java代码与本地代码的...

    完美解决java读取excel内存溢出问题.rar

    在Java开发中,处理大型Excel文件时,可能会遇到内存溢出的问题。这通常是由于Java的默认内存设置不足以处理大量数据导致的。本解决方案主要针对使用Apache POI库进行Excel读取时遇到的这类问题。 首先,Apache POI...

    kettle内存溢出(Java heap space)以及解决方法.docx

    5. **代码优化**:检查并优化Kettle的自定义脚本或Java代码,避免无用的对象创建和内存泄漏。 6. **定期清理和释放资源**:确保Kettle在处理完数据后,及时释放不再使用的对象和资源,避免内存碎片。 最后,监控...

    java解决大批量数据导出Excel产生内存溢出的方案

    - 使用内存分析工具(如VisualVM或YourKit Java Profiler)监控内存使用情况,找出内存泄漏或不必要的对象引用,进行优化。 通过这些方法,我们可以在处理大量数据导出到Excel时避免内存溢出问题,同时保持程序的...

    Qt内存溢出检测

    在C++中,程序员需要手动分配和释放内存,如果没有正确地释放已分配的内存,就会出现内存泄漏,长期累积可能导致内存溢出。 Qt库中提供了智能指针(如QPointer、QSharedPointer)和对象所有权(如QObject的parent-...

    深入理解Java虚拟机——Java内存区域与内存溢出异常.xmind

    这是自己读《深入理解Java虚拟机》时候用XMind建立的思维导图,目的是为了能够帮助自己整理、梳理相关的知识以及方便自己日后的回顾,帮助自己建立起关于JVM的知识体系,里边也有一些对相关内容的补充,通过备注的...

    Java内存溢出和内存泄露共4页.pdf.zip

    Java内存管理是编程人员在开发高并发、高性能应用时必须...理解并掌握Java内存管理机制,以及如何预防和处理内存溢出和内存泄露,是每个Java开发者必备的技能。通过上述方法,我们可以有效地提升程序的稳定性和性能。

    内存溢出配置,内存溢出配置

    内存溢出配置是IT行业中,尤其是在Java应用开发与运维领域中的一个重要话题,它涉及到系统资源管理、性能调优以及故障排查等多个方面。标题与描述中重复提到“内存溢出配置”,这表明了对这一主题的关注与重视。接...

    Python内存泄漏和内存溢出的解决方案

    虽然Python有内置的垃圾回收机制,但仍然可能出现内存泄漏和内存溢出的问题,影响程序的稳定性和效率。 **一、Python内存泄漏** 内存泄漏通常是由于以下几个原因引起的: 1. **C扩展模块的内存泄漏**:使用C语言...

    JAVA内存溢出详解.doc

    Java内存溢出(Out Of Memory,OOM)是Java应用程序运行时常见的问题,它通常发生在程序对内存需求超过了Java虚拟机(JVM)所能提供的可用内存时。本文将深入探讨Java内存溢出的原因、表现以及如何解决。 1. **Java...

    Java内存溢出解决办法

    Java内存溢出问题,全称为Java OutOfMemoryError,是Java开发者经常遇到的运行时异常。内存溢出通常发生在程序运行过程中,系统无法为运行的应用程序分配足够的内存资源,导致程序无法正常执行。理解并解决Java内存...

    图片过大引起的内存溢出解决方案

    ### 图片过大引起的内存溢出解决方案 在Android开发过程中,我们经常会遇到因加载大尺寸图片而引发的`OutOfMemoryError`(内存溢出错误)。这种问题通常发生在使用`BitmapFactory`来加载图片时,尤其是在资源有限的...

    java 内存溢出分析工具 HeapAnalyzer

    Java内存溢出(Out of Memory,OOM)是Java应用程序中常见的问题,会导致程序崩溃或性能急剧下降。HeapAnalyzer是一款强大的工具,专为分析Java应用程序的内存状况,特别是针对内存溢出问题进行诊断。本文将详细介绍...

    Java 内存溢出解决办法

    Java内存溢出问题通常指的是程序在试图分配内存时,无法找到足够的连续内存空间而抛出的异常。在Java中,内存分为几个区域:堆(Heap)、栈(Stack)、方法区(Method Area,Java 8后被元空间取代)以及程序计数器和...

    内存溢出解决

    根据内存溢出的位置不同,可以将Java内存溢出分为以下几种类型: - **堆内存溢出**:最常见的一种内存溢出类型,通常由于对象长时间未被垃圾回收导致。 - **方法区溢出**:当方法区无法再创建新的类时,就会发生方法...

Global site tag (gtag.js) - Google Analytics