导航:首页 > 编程语言 > java内存溢出

java内存溢出

发布时间:2025-02-18 15:13:54

A. java程序内存溢出一般什么原因

JVM内存设置小了 或者一次性读的数据过大 例如list vertor

一、内存溢出类型

1、java.lang.OutOfMemoryError: PermGen space

JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。如果web
app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。

PermGen space的全称是Permanent Generation
space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen
space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen
space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对jsP进行pre
compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。

一个最佳的配置例子:(经过本人验证,自从用此配置之后,再未出现过tomcat死掉的情况)

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

2、java.lang.OutOfMemoryError: Java heap space

第一种情况是个补充,主要存在问题就是出现在这个情况中。其默认空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。如果内存剩余不到40%,JVM就会增大堆到Xmx设置的值,内存剩余超过70%,JVM就会减小堆到Xms设置的值。所以服务器的Xmx和Xms设置一般应该设置相同避免每次GC后都要调整虚拟机堆的大小。假设物理内存无限大,那么JVM内存的最大值跟操作系统有关,一般32位机是1.5g到3g之间,而64位的就不会有限制了。

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

垃圾回收GC的角色

JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收:

当应用程序线程空闲;另一个是java内存堆不足时,会不断调用GC,若连续回收都解决不了内存堆不足的问题时,就会报out of
memory错误。因为这个异常根据系统运行环境决定,所以无法预期它何时出现。

根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会。

为了避免这些问题,程序的设计和编写就应避免垃圾对象的内存占用和GC的开销。显示调用System.GC()只能建议JVM需要在内存中对垃圾对象进行回收,但不是必须马上回收,

一个是并不能解决内存资源耗空的局面,另外也会增加GC的消耗。

二、JVM内存区域组成

简单的说java中的堆和栈

java把内存分两种:一种是栈内存,另一种是堆内存

1。在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;

2。堆内存用来存放由new创建的对象和数组

在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理

堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢;

栈的优势是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性。

java堆分为三个区:New、Old和Permanent

GC有两个线程:

新创建的对象被分配到New区,当该区被填满时会被GC辅助线程移到Old区,当Old区也填满了会触发GC主线程遍历堆内存里的所有对象。Old区的大小等于Xmx减去-Xmn

java栈存放

栈调整:参数有+UseDefaultStackSize -Xss256K,表示每个线程可申请256k的栈空间

每个线程都有他自己的Stack

三、JVM如何设置虚拟内存

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

提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。

提示:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。

默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC
后调整堆的大小。

提示:假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。

简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,

这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了

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

提示:设置NewSize、MaxNewSize相等,"new"的大小最好不要大于"old"的一半,原因是old区如果不够大会频繁的触发"主" GC
,大大降低了性能

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

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

解决方法:手动设置Heap size

修改TOMCAT_HOME/bin/catalina.bat

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

JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"

四、性能检查工具使用

定位内存泄漏:

JProfiler工具主要用于检查和跟踪系统(限于Java开发的)的性能。JProfiler可以通过时时的监控系统的内存使用情况,随时监视垃圾回收,线程运行状况等手段,从而很好的监视JVM运行情况及其性能。

1. 应用服务器内存长期不合理占用,内存经常处于高位占用,很难回收到低位;

2. 应用服务器极为不稳定,几乎每两天重新启动一次,有时甚至每天重新启动一次;

3. 应用服务器经常做Full GC(Garbage Collection),而且时间很长,大约需要30-40秒,应用服务器在做Full
GC的时候是不响应客户的交易请求的,非常影响系统性能。

因为开发环境和产品环境会有不同,导致该问题发生有时会在产品环境中发生,通常可以使用工具跟踪系统的内存使用情况,在有些个别情况下或许某个时刻确实是使用了大量内存导致out
of memory,这时应继续跟踪看接下来是否会有下降,

如果一直居高不下这肯定就因为程序的原因导致内存泄漏。

五、不健壮代码的特征及解决办法

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

对于仍然有指针指向的实例,jvm就不会回收该资源,因为垃圾回收会将值为null的对象作为垃圾,提高GC回收机制效率;

2、我们的程序里不可避免大量使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域;

String str = "aaa";

String str2 = "bbb";

String str3 = str + str2;//假如执行此次之后str
,str2以后再不被调用,那它就会被放在内存中等待Java的gc去回收,程序内过多的出现这样的情况就会报上面的那个错误,建议在使用字符串时能使用StringBuffer就不要用String,这样可以省不少开销;

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、一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成 Out Of Memory Error
的状况,这时就大概要计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。

B. Java内存设置详解(含内存溢出问题的解决)

Java内存溢出问题详解,主要涉及三种情况:Java heap space、PermGen space和Stack Overflow。

1. Java heap space溢出常见于JVM Heap(堆)空间不足,导致应用运行时出现“java.lang.OutOfMemoryError: Java heap space”异常。JVM在启动时自动配置Heap的大小,初始空间为物理内存的1/64,最大空间不超过物理内存。可通过-Xms和-Xmx参数手动调整Heap大小。

Heap空间由Young Generation和Tenured Generation组成。若年轻代和老年代的总可用空间不足2%,且应用在98%的时间内需要进行垃圾回收,即抛出此异常。

解决方法:根据应用需求调整Heap大小。

2. PermGen space溢出则源于内存永久保存区域,主要用于存储Class和Meta信息。Class在被加载时放入PermGen space,而JVM不执行主程序期间的垃圾回收,导致大量Class加载后内存空间不足。异常信息为“java.lang.OutOfMemoryError: PermGen space”。

解决方法:手动设置MaxPermSize参数调整PermGen空间大小。

3. Stack Overflow错误发生在函数调用深度过大,超过了栈区的容量。常见于递归调用过深或错误设计的代码结构。

解决方法:优化代码逻辑,减少不必要的递归调用。

为解决Java内存溢出问题,需要根据具体情况调整JVM参数。在Linux环境下调整Tomcat配置,包括修改`catalina.sh`文件或修改注册表键值。Windows环境下的Tomcat服务需要通过注册表或修改特定的`.exe`文件来调整配置。在MyEclipse中启动Tomcat时,可在Java VM参数中添加特定选项来优化内存使用。

C. 内存泄漏和内存溢出有啥区别

在Java编程中,内存管理是一个关键环节,涉及两种主要问题:内存溢出和内存泄漏。本文将深入探讨这两种问题的区别以及如何处理。

首先,我们来谈谈内存溢出,这通常发生在JVM的几个内存区域中,除了程序计数器外,包括Java堆、虚拟机栈、本地方法栈、方法区和运行时常量池等。

具体来说,Java堆溢出是由于对象实例数量的不断增长,当总容量触及最大堆容量限制时,就会引发内存溢出异常。代码示例中,我们设置了启动时的JVM参数,限制内存大小为20M,不允许扩展,并通过-XX:+HeapDumpOnOutOf-MemoryError参数让虚拟机在内存溢出时Dump出内存堆转储快照。通过分析内存映像工具(如JProfiler、Eclipse Memory Analyzer等)的堆转储快照,可以定位到问题代码,从而找到解决方案。常见的堆相关参数如-Xms、-Xmx、-Xmn、-XX:NewRatio、-XX:SurvivorRatio和-XX:MaxTenuringThreshold等,都是用来优化内存管理的。

接着,我们讨论栈相关的问题。对于HotSpot虚拟机,虚拟机栈和本地方法栈是合二为一的。栈的容量只能由-Xss参数来设定,因此只有StackOverflowError和OutOfMemoryError两种异常。StackOverflowError通常发生在栈帧过大或者栈容量不足的情况下,而OutOfMemoryError则可能由于创建大量线程导致。在系统资源受限的情况下,线程数过多可能导致内存溢出。

除了栈,方法区和运行时常量池也存在溢出问题。随着程序运行,这些区域的内存使用量可能会增长,导致内存溢出。例如,方法区的内存管理在JDK 7之后发生了变化,字符串常量池移动到了堆中,而在JDK 8中,元空间被直接内存中划分出来。对于字符串的intern()操作,如果频繁使用并创建大量字符串对象,可能触发方法区的内存溢出。

最后,我们讨论内存泄漏,它指的是不应该被垃圾回收的对象未能被回收的情况。当一个对象的生命周期长于引用它的对象时,垃圾回收器不会回收该对象,从而导致内存逐渐被占用,最终导致系统性能下降甚至崩溃。处理内存泄漏通常需要对代码进行深入分析,找出对象引用的生命周期问题,并进行相应的优化。

总之,内存溢出和内存泄漏是Java开发中常见的问题,通过了解它们的本质、影响和解决方法,可以有效提高程序的稳定性和性能。对于内存管理问题,合理配置JVM参数、使用内存分析工具以及进行代码优化是关键。

D. java内存溢出OutOfMemoryError异常

Java内存溢出异常,通常表现为OutOfMemoryError,涉及Java堆、虚拟机栈、本地方法栈以及方法区的管理。首先,Java堆的设置通过参数-Xms和-Xmx来控制,最小值为-Xms20m,最大值如果不一致,堆会自动扩展。年轻代的大小则通过-Xmn指定。

在遇到内存溢出时,可以设置-XX:+HeapDumpOnOutOfMemoryError,这样当内存溢出时,会自动保存堆转储文件,便于后续分析。在Eclipse中,可通过"debug As"->"open debug dialog"进行配置,然后借助MAT插件进行堆转储文件的分析。

虚拟机栈和本地方法栈的溢出则由-Xss控制,线程的栈大小默认为1M(JDK1.5之后),如果线程过多导致溢出,可以考虑减小-Xmx来增加线程数量,同时减小每个线程的栈容量。栈深度一般1000-2000是安全范围,过深可能会引发StackOverFlow异常。

方法区和运行时常量池的内存管理通过-PermSize和-MaxPermSize来设定,方法区默认占物理内存的1/64。如果内存溢出,可能需要调整这两个参数的大小。

最后,本机直接内存的大小由-XX:MaxDirectMemorySize来控制,如果不设置,其大小默认与-Xmx相同。直接内存溢出通常与大数据处理或内存密集型操作相关,需谨慎调整。

E. java中堆的内存泄漏和内存溢出及问题解决方案有哪些

本文从Java中堆的内存泄漏和内存溢出问题出发,探讨了Java堆空间不足导致的错误原因,以及解决方案。Java应用的内存限制主要由堆空间和Permgen区决定,大小在JVM启动时设置,或通过-Xmx和-XX:MaxPermSize参数自定义。当应用程序尝试在堆空间中添加更多数据时,会触发java.lang.OutOfMemoryError: Java heap space错误。此错误常见原因是应用程序内存需求超过JVM允许的堆空间大小。

除了直接内存分配错误,内存泄漏也是引发内存溢出的常见原因之一。Java的自动内存管理依赖垃圾收集器(GC)定期检查并回收未使用的对象。内存泄漏发生在程序不再使用某些对象但GC未能识别并释放它们,导致这些对象无限期地占用堆空间。一个简单的示例是创建无限增长的缓存,由于缺少equals()实现,对象无法被正确识别并回收。

解决内存泄漏的方法之一是优化代码,确保对象被正确管理,包括实现适当的equals()和hashCode()方法,避免无用对象的积累。此外,可以使用工具如Plumbr进行内存分析,以自动检测并提供根本原因分析,帮助识别导致内存使用过高的数据结构。

当增加堆空间不足以解决问题时,需要深入分析代码,定位内存使用热点。这可以通过手动代码审查、内存分析工具或自动根本原因检测工具完成。一旦确定问题所在,可以通过优化数据结构、调整算法或减少对象使用来解决内存泄漏问题。

如果增加堆空间后问题依然存在,可以尝试增加堆大小。在JVM配置中使用-Xmx参数指定最大堆空间,如-Xmx1024m将堆大小设置为1024MB。确保根据实际需求调整堆空间大小,避免资源浪费。

总结,理解Java堆空间的管理和内存泄漏的原理是解决内存溢出问题的关键。通过合理配置JVM参数、优化代码、使用内存分析工具,可以有效地管理内存使用,确保Java应用的稳定运行。

阅读全文

与java内存溢出相关的资料

热点内容
怎样变换文件存储格式 浏览:208
飞常准的数据来自哪里 浏览:844
ug100如何编程画线 浏览:870
文件夹999找不到 浏览:145
win1014393最新版本号 浏览:100
java基本类型大小 浏览:516
word2007不能插入页码 浏览:968
vb读取文件并判断 浏览:6
php图片和程序分离 浏览:412
安卓面试非计算机专业 浏览:228
u盘的光盘文件怎么驱动 浏览:34
如何锁定c盘不下文件 浏览:359
浙江推广网站建设怎么做 浏览:478
word文件只有10页怎么增加 浏览:921
itunes下载的系统在哪个文件夹 浏览:605
个性化linux全名要求 浏览:40
数据表格制图小红点如何去掉 浏览:244
查询iphone版本信息失败怎么办 浏览:978
电脑版微信下载的文件保存在哪里 浏览:367
linuxsocket转发 浏览:32

友情链接