首页 > 编程知识 正文

java中内存溢出详解(内存溢出是一种java异常)

时间:2023-12-24 12:05:23 阅读:320184 作者:RMDW

本文目录一览:

java内存溢出怎么解决?

第一对所有的代码包括页面中的java代码都进行一遍彻底的回顾检查,

1.对那些静态(static)的对象要特别留神,特别是类型为Map,List,Set的,静态的变量会一直驻存在内存中,生命周期比较长,不会被垃圾器回收。

2.对于代码,要审查是否生成了大量的冗余的对象,还有一些逻辑业务处理的类,

算法是否过于复杂,调整算法,对于代码认真审查,再仔细重构一遍代码,能提高代码质量,提高程序运行稳定性。

3.Java中的内存溢出大都是因为栈中的变量太多了。其实内存有的是。建议不用的尽量设成null以便回收,多用局部变量,少用成员变量。

1),变量所包含的对象体积较大,占用内存较多。

2),变量所包含的对象生命周期较长。

3),变量所包含的对象数据稳定。

4),该类的对象实例有对该变量所包含的对象的共享需求。

4.在我的程序中对静态变量的优化后,使程序占用内存量至少提升了5k-10k。所以也不容忽视。

第二还有就是String类相关的东西:

1.字符串累加的时候一定要用StringBuffer的append方法,不要使用+操作符连接两个字符串。差别很大。而且在循环或某些重复执行的动作中不要去创建String对象,因为String对象是要用StringBuffer对象来处理的,一个String对象应该是产生了 3个对象(大概是这样:))。

2.字符串length()方法来取得字符串长度的时候不要把length放到循环中,可以在循环外面对其取值。(包括vector的size方法)。特别是循环次数多的时候,尽量把length放到循环外面。

int size = xmlVector.size();

for (int i = 2; i size; i++) {

。。。

}

3 写代码的时候处理内存溢出

try{

//do sth

....

}catch (outofmemoryerror e){//可以用一个共通函数来执行.

system.out.print (“no memory! ”);

system.gc();

//do sth again

....

} 4.对于频繁申请内存和释放内存的操作,还是自己控制一下比较好,但是System.gc()的方法不一定适用,最好使用finallize强制执行或者写自己的finallize方法。 Java 中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。

java内存溢出是什么情况?

首先先说一下JVM内存结构问题,JVM为两块:PermanentSapce和HeapSpace,其中

Heap = }。PermantSpace负责保存反射对象,一般不用配置。JVM的Heap区可以通过-X参数来设定。

当一个URL被访问时,内存申请过程如下:

A. JVM会试图为相关Java对象在Eden中初始化一块内存区域

B. 当Eden空间足够时,内存申请结束。否则到下一步

C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收), 释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区

D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区

E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)

F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”

JVM调优建议:

ms/mx:定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;mx为最大可占用的YOUNG+OLD内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

NewSize/MaxNewSize:定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

PermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

SurvivorRatio:设置Survivor空间和Eden空间的比例

内存溢出的可能性

1. OLD段溢出

这种内存溢出是最常见的情况之一,产生的原因可能是:

1) 设置的内存参数过小(ms/mx, NewSize/MaxNewSize)

2) 程序问题

单个程序持续进行消耗内存的处理,如循环几千次的字符串处理,对字符串处理应建议使用StringBuffer。此时不会报内存溢出错,却会使系统持续垃圾收集,无法处理其它请求,相关问题程序可通过Thread Dump获取(见系统问题诊断一章)单个程序所申请内存过大,有的程序会申请几十乃至几百兆内存,此时JVM也会因无法申请到资源而出现内存溢出,对此首先要找到相关功能,然后交予程序员修改,要找到相关程序,必须在Apache日志中寻找。

当Java对象使用完毕后,其所引用的对象却没有销毁,使得JVM认为他还是活跃的对象而不进行回收,这样累计占用了大量内存而无法释放。由于目前市面上还没有对系统影响小的内存分析工具,故此时只能和程序员一起定位。

2. Perm段溢出

通常由于Perm段装载了大量的Servlet类而导致溢出,目前的解决办法:

1) 将PermSize扩大,一般256M能够满足要求

2) 若别无选择,则只能将servlet的路径加到CLASSPATH中,但一般不建议这么处理

3. C Heap溢出

系统对C Heap没有限制,故C Heap发生问题时,Java进程所占内存会持续增长,直到占用所有可用系统内存

参数说明:

JVM 堆内存(heap)设置选项

参数格式

说 明

设置新对象生产堆内存(Setting the Newgeneration heap size)

-XX:NewSize

通过这个选项可以设置Java新对象生产堆内存。在通常情况下这个选项的数值为1 024的整数倍并且大于1MB。这个值的取值规则为,一般情况下这个值-XX:NewSize是最大堆内存(maximum heap size)的四分之一。增加这个选项值的大小是为了增大较大数量的短生命周期对象

增加Java新对象生产堆内存相当于增加了处理器的数目。并且可以并行地分配内存,但是请注意内存的垃圾回收却是不可以并行处理的

设置最大新对象生产堆内存(Setting the maximum New generation heap size)

-XX:MaxNewSize

通过这个选项可以设置最大Java新对象生产堆内存。通常情况下这个选项的数值为1 024的整数倍并且大于1MB

其功用与上面的设置新对象生产堆内存-XX:NewSize相同

设置新对象生产堆内存的比例(Setting New heap size ratios)

-XX:SurvivorRatio

新对象生产区域通常情况下被分为3个子区域:伊甸园,与两个残存对象空间,这两个空间的大小是相同的。通过用-XX:SurvivorRatio=X选项配置伊甸园与残存对象空间(Eden/survivor)的大小的比例。你可以试着将这个值设置为8,然后监控、观察垃圾回收的工作情况

设置堆内存池的最大值(Setting maximum heap size)

-Xmx

通过这个选项可以要求系统为堆内存池分配内存空间的最大值。通常情况下这个选项的数值为1 024的整数倍并且大于1 MB

一般情况下这个值(-Xmx)与最小堆内存(minimum heap size –Xms)相同,以降低垃圾回收的频度

取消垃圾回收

-Xnoclassgc

这个选项用来取消系统对特定类的垃圾回收。它可以防止当这个类的所有引用丢失之后,这个类仍被引用时不会再一次被重新装载,因此这个选项将增大系统堆内存的空间

设置栈内存的大小

-Xss

这个选项用来控制本地线程栈的大小,当这个选项被设置的较大(2MB)时将会在很大程度上降低系统的性能。因此在设置这个值时应该格外小心,调整后要注意观察系统的性能,不断调整以期达到最优

最后说一句,你的机器的连接数设置也至关重要,连接的关闭最好把时间设置的少些,那些连接非常耗费资源。也是引起内存泄露的主要原因。

Java常见的几种内存溢出

1.jvm管理的内存大致包括三种不同类型的内存区 域:Permanent Generation space(永久保存区域)、Heap space(堆区域)、Java Stacks(Java栈)。

2.Java程序的每个线程中都有一个独立的堆栈。容易发生内存溢出问题的内存空间包括:Permanent Generation space和Heap space。

3.因为字体多,所以提供参考链接:

【java中三种常见内存溢出错误的处理方法 】

Java内存溢出主要有哪些类型?

主要有三种类型

第一种OutOfMemoryError: PermGen space

发生这种问题的原意是程序中使用了大量的jar或class,使java虚拟机装载类的空间不够,与Permanent Generation space有关。解决这类问题有以下两种办法:

1. 增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中XX:PermSize是初始永久保存区域大小,XX:MaxPermSize是最大永久保存区域大小。如针对tomcat6.0,在catalina.sh 或catalina.bat文件中一系列环境变量名说明结束处(大约在70行左右) 增加一行:

JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"

如果是windows服务器还可以在系统环境变量中设置。感觉用tomcat发布sprint+struts+hibernate架构的程序时很容易发生这种内存溢出错误。使用上述方法,我成功解决了部署ssh项目的tomcat服务器经常宕机的问题。

2. 清理应用程序中web-inf/lib下的jar,如果tomcat部署了多个应用,很多应用都使用了相同的jar,可以将共同的jar移到tomcat共同的lib下,减少类的重复加载。

第二种OutOfMemoryError: Java heap space

发生这种问题的原因是java虚拟机创建的对象太多,在进行垃圾回收之间,虚拟机分配的到堆内存空间已经用满了,与Heap space有关。解决这类问题有两种思路:

1. 检查程序,看是否有死循环或不必要地重复创建大量对象。找到原因后,修改程序和算法。

我以前写一个使用K-Means文本聚类算法对几万条文本记录(每条记录的特征向量大约10来个)进行文本聚类时,由于程序细节上有问题,就导致了Java heap space的内存溢出问题,后来通过修改程序得到了解决。

2. 增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m

第三种OutOfMemoryError:unable to create new native thread

这种错误在Java线程个数很多的情况下容易发生

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。