JVM–基础–29–内存溢出
1、什么是内存溢出
就是应用系统所需的内存大于虚拟机的堆内存
2、内存溢出的原因
- 内存中加载的数据量过于庞大,如一次从数据库取出过多数据
- 集合类中对对象的引用,使用完后未清空,使得JVM不能回收
- 代码中存在死循环或循环产生过多重复的对象实体
3、解决办法
3.1、修改JVM启动参数,直接增加内存。
3.2、检查错误日志,查看"OutOfMemory"错误前是否有其它异常或错误。
3.3、对代码进行走查和分析,
- 检查代码中是否有死循环或递归调用。
- 检查是否有大循环重复产生新对象实体。
- 检查对数据库查询中,是否有一次获得全部数据的查询,而没有使用分页。
- 检查List、MAP等集合对象是否有使用完后,未清除的问题。
- List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
3.4、尽早释放无用对象的引用。
使用临时变量的时候,让引用变量在退出活动域后,自动设置为 null ,暗示垃圾收集器来收集该对象,防止发生内存泄露。
3.5、我们的程序里不可避免大量使用字符串处理,避免使用 String ,因为每一个 String 对象都得独立占用内存一块区域,所有应使用 StringBuffer
String str = "aaa";
String str2 = "bbb";
String str3 = str + str2;// 假如执行此次之后 str ,str2 以后再不被调用 , 那它就会被放在内存中等待 Java 的 gc 去回收 , 程序内过多的出现这样的情况就会报上面的那个错误 .
3.6、尽量少用静态变量,因为静态变量是全局的, GC 不会回收的
3.7、避免集合中创建对象尤其是大对象。
因为 JVM 会突然需要大量内存,这时必然会触发 GC 优化系统内存环境
举例
- 显示的声明数组空间,而且申请数量还极大。
- 比如:有个excel文件上传的功能,excel内容有非常大,每次上传都导致jvm需要大量的内存。
3.8、尽量运用对象池技术以提高系统性能
生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏。
例如:大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。
3.9、不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。
可以适当的使用hashtable, vector创建一组对象容器,然后从容器中去取那些对象,而不用每次 new 之后又丢弃