JVM–基础–29–内存溢出

1、什么是内存溢出

就是应用系统所需的内存大于虚拟机的堆内存

2、内存溢出的原因

  1. 内存中加载的数据量过于庞大,如一次从数据库取出过多数据
  2. 集合类中对对象的引用,使用完后未清空,使得JVM不能回收
  3. 代码中存在死循环或循环产生过多重复的对象实体

3、解决办法


3.1、修改JVM启动参数,直接增加内存。

3.2、检查错误日志,查看"OutOfMemory"错误前是否有其它异常或错误。

3.3、对代码进行走查和分析,

  1. 检查代码中是否有死循环或递归调用。
  2. 检查是否有大循环重复产生新对象实体。
  3. 检查对数据库查询中,是否有一次获得全部数据的查询,而没有使用分页。
  4. 检查List、MAP等集合对象是否有使用完后,未清除的问题。
  1. 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 优化系统内存环境

举例
  1. 显示的声明数组空间,而且申请数量还极大。
  2. 比如:有个excel文件上传的功能,excel内容有非常大,每次上传都导致jvm需要大量的内存。

3.8、尽量运用对象池技术以提高系统性能

生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏。
例如:大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。

3.9、不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。

可以适当的使用hashtable, vector创建一组对象容器,然后从容器中去取那些对象,而不用每次 new 之后又丢弃