内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,便是溢出

要点

1、内存透露是指程序中间动态分配了内存,但在程序结束时没有开释这部分内存,从而造成那部分内存不可用的情形,重启打算机可以办理,但也有可能再次发生内存透露,内存透露和硬件没有关系,它是由软件设计毛病引起的。

2、内存泄露可以分为4类:

jspoverflow详解内存溢出Memory Overflow和内存泄漏Memory Leak的差别 Vue.js

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

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

3)一次性内存泄露。
发生内存泄露的代码只会被实行一次,或者由于算法上的毛病,导致总会有一块仅且一块内存发生泄露。
比如,在类的布局函数等分配内存,在析构函数中却没有开释该内存,以是内存泄露只会发生一次。

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

3、内存溢出即用户在对其数据缓冲区操作时,超过了其缓冲区的边界;尤其是对缓冲区写操作时,缓冲区的溢出很可能导致程序的非常。

4、内存溢出类型:

1)java.lang.OutOfMemoryError:PermGen space

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

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) 开启大型文件或从数据库中一次取了太多的数据。

干系问题

1. Java中会存在内存泄露吗?

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. 内存透露、溢出的异同?

同:都会导致运用程序运行涌现问题,性能低落或挂起。

异:

1) 内存透露是导致内存溢出的缘故原由之一;内存透露积累起来将导致内存溢出。

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

3. 如何检测内存透露?

可以通过一些性能监测剖析工具,如 JProfiler、OptimizeitProfiler。

4. 如何避免内存透露、溢出?

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的办法办理。

5)只管即便利用工具池技能以提高系统性能。

生命周期长的工具拥有生命周期短的工具时随意马虎引发内存泄露,例如大凑集工具拥有大数据量的业务工具的时候,可以考虑分块进行处理,然后办理一块开释一块的策略。

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

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

7) 优化配置。

5. 内存溢出的办理方案?

一是从代码层面进行优化完善,只管即便避免该情形发生;

二是调度优化做事器配置:

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=-Xms2048m -Xmx2048m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m

后面会分享更多关于devops和DBA方面的内容,感兴趣的朋友可以关注下~