一、 Permanent Generation space问题
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决方法也一定是加大内存。说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。
改正方法:-Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m
二、java.lang.OutOfMemoryError: Java heap space
Heap size 设置
JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,
其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可
进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。
提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
解决方法:手动设置Heap size
修改TOMCAT_HOME/bin/catalina.sh
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
三、实例,以下给出1G内存环境下java jvm 的参数设置参考:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "
Lily Notes:
除了以上从网络转载的,我自己总结处理OOM的还有以下方式:
1.首先是检查自己的代码是不是存在所谓的“内存泄漏”,就是某些个引用在程序中已经没有用了,却没有被置为NULL,导致GC不会去释放它,这样空闲的内存会越来越小,容易导致OOM的问题。所以要养成好习惯,对于已经没有用的引用应该要置为NULL,特别是集合类的引用容易忽视掉
2.其次还是从自己身上找问题,看看是不是可以优化自己的代码,不需要new这么多对象,例如我曾经有见过同事的代码,需要从数据库里面查出符合特定条件的一些数据,再将它们装入list显示出来,他的代码是把数据库所有东西都查出来,然后在自己代码里面来过滤,最后再显示,其实这是不好的逻辑,假如我们查询的时候就把过滤条件加进去,那是不是就不会返回那么多数据呢,这样不但可以减少资源的使用,而且提高了程序的效能。
3.明白String和StringBuffer的区别,不在循环里面new对象等。
4.主动调用System.gc(),虽然GC不保证调用后一定会去执行GC,但是有时候多主动调用几次,还是有效果的,我的理解,类似快马加鞭的感觉吧,哈哈
5.使用弱引用SoftReference 和 WeakReference
如果你想写一个 Java 程序,观察某对象什么时候会被垃圾收集的执行绪清除,你必须要用一个 reference 记住此对象,以便随时观察,但是却因此造成此对象的 reference 数目一直无法为零, 使得对象无法被清除。
java.lang.ref.WeakReference
不过,现在有了 Weak Reference 之后,这就可以迎刃而解了。如果你希望能随时取得某对象的信息,但又不想影响此对象的垃圾收集,那么你应该用 Weak Reference 来记住此对象,而不是用一般的 reference。
01 A obj = new A();
02
03 WeakReference wr = new WeakReference(obj);
04
05 obj = null;
06
07 //等待一段时间,obj对象就会被垃圾回收
08
09 ...
10
11 if (wr.get()==null) {
12
13
14 System.out.println("obj 已经被清除了 ");
15
16
17 } else {
18
19 System.out.println("obj 尚未被清除,其信息是 "+obj.toString());
20
21 }
22
23 ...
在此例中,透过 get() 可以取得此 Reference 的所指到的对象,如果传出值为 null 的话,代表此对象已经被清除。
这类的技巧,在设计 Optimizer 或 Debugger 这类的程序时常会用到,因为这类程序需要取得某对象的信息,但是不可以 影响此对象的垃圾收集。
1 java.lang.ref.SoftReference
Soft Reference 虽然和 Weak Reference 很类似,但是用途却不同。 被 Soft Reference 指到的对象,即使没有任何 Direct Reference,也不会被清除。一直要到 JVM 内存不足时且 没有 Direct Reference 时才会清除,SoftReference 是用来设计 object-cache 之用的。如此一来 SoftReference 不但可以把对象 cache 起来,也不会造成内存不足的错误 (OutOfMemoryError)。我觉得 Soft Reference 也适合拿来实作 pooling 的技巧。
1 A obj = new A();
2
3 SoftRefenrence sr = new SoftReference(obj);
引用时
显示代码
打印
01 if(sr!=null){
02
03 obj = sr.get();
04
05 }else{
06
07 obj = new A();
08
09 sr = new SoftReference(obj);
10
11 }
6.实在没辙了,那就只能改java的heap或permGenSpace大小了