- 原因:程序在申请内存时,没有足够的空间
- 栈溢出
- 方法死循环递归调用(StackOverflowError)
- 不断建立线程(OutOfMemoryError)
- 堆溢出
- 不断创建对象,分配对象大于最大堆的大小(OutOfMemoryError)
- 直接内存
- JVM 分配的本地直接内存大小大于 JVM 的限制,可以通过-XX:MaxDirectMemorySize 来设置(不设置的话默认与堆内存最大值一样,也会出现OOM 异常)
- 方法区溢出
- 原因:主要是代码写的不合理,程序在申请内存后,无法释放已申请的内存空间
- 长生命周期的对象持有短生命周期对象的引用
- 将 ArrayList 设置为静态变量,然后不断地向ArrayList中添加对象,则 ArrayList 容器中的对象在程序结束之前将不能被释放,从而造成内存泄漏
- 连接未关闭
- 如数据库连接、网络连接和IO连接等等,只有连接被关闭后,垃圾收集器才会回收对应的对象
- 变量作用域不合理
- 一个变量的定义作用范围大于其使用范围
- 没有及时的把对象设置为null
- 内部类持有外部类
- Java的非静态内部类,会隐式地持有外部类的引用,如果内部类的生命周期长于外部类的生命周期,程序很容易造成内存泄露
- 解决方法:将非静态内部类改成静态内部类
- Hash值改变
- 在集合中,如果修改了对象中的那些参与计算哈希值的字段,会导致无法从集合中单独删除当前对象,造成内存泄露
-
Jprofile