------------------------错误信息------------------------
OutOfMemory:Java heap space
翻译成中文就是内存溢出,堆空间
------------------------导致错误的动作------------------------
从数据库中查询“大量”信息时出错
------------------------错误分析------------------------
内存溢出就是调入JVM内存的东西大于JVM本身的内存,东西盛放不下了于是报错。
产生原因自然有二:
1.内存太小,就跟早期256M内存的电脑跑个QQ都卡是一个道理。
2.装的东西太多,垃圾没有及时清理掉,占用太多空间。
即使从正常逻辑来考虑也是这两方面,因此解决问题也要从两方面下手。
------------------------解决------------------------
第一点,JVM原来的内存到底多大?
第二点,程序到底运行了什么,使得占用内存太大,而且清理不及时?
1、JVM默认分配64M的空间。如果考虑到程序运行时占用空间可能过大,可以进行调配。调配方式如下:
在MyEclipse中,选中被运行的类或工程,点击菜单‘Run as ->Open Run Dialog...’,选择(x)=Argument标签页下的vm arguments框里输入 -Xmx512m, 保存运行就ok了
2.(1)不要试图去假定垃圾收集发生的时间,这一切都是未知的。比如,方法中的一个临时对象在方法调用完毕后就变成了无用对象,这个时候它的内存就可以被释放。
(2)Java
中提供了一些和垃圾收集打交道的类,而且提供了一种强行执行垃圾收集的方法--调用System.gc(),但这同样是个不确定的方法。Java
中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。
(3)
挑选适合自己的垃圾收集器。一般来说,如果系统没有特殊和苛刻的性能要求,可以采用JVM的缺省选项。否则可以考虑使用有针对性的垃圾收集器,比如增量收
集器就比较适合实时性要求较高的系统之中。系统具有较高的配置,有比较多的闲置资源,可以考虑使用并行标记/清除收集器。
(4)关键的也是难把握的问题是内存泄漏。良好的编程习惯和严谨的编程态度永远是最重要的,不要让自己的一个小错误导致内存出现大漏洞。
(5)尽早释放无用对象的引用。
大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为null,暗示垃圾收集器来收集该对象,还必须注意该引用的对象是否被监听,如果有,则要去掉监听器,然后再赋空值。
就是说,对于频繁申请内存和释放内存的操作,还是自己控制一下比较好,但是System.gc()的方法不一定适用,最好使用finallize强制执行或者写自己的finallize方法。
综上,解决方法是:1增加JVM的内存大小;2垃圾内存及时置空,以让JVM尽快自动回收。释放内存空间。
------------------------扩展------------------------
依上述所说,下边的例子必定会报该错误:
byte[] bytes=new byte[1024*1024*65];
经运行实践,的确如此,为什么呢?因为你分配的内存大小为65M,而实际上JVM分配内存为64M,当然会溢出了~~~
该贴由koei转至本版2014-5-2 16:25:13