Java死循环while/for中无限new对象可能会出现OOM问题,也可能不会出现OOM问题。后续更新。。。
各种OOM的情况
1. 堆溢出-java.lang.OutOfMemoryError: Java heap space。
2. 栈溢出-java.lang.OutOfMemorryError。
3. 栈溢出-java.lang.StackOverFlowError。
4. 元信息溢出-java.lang.OutOfMemoryError: Metaspace。
5. 直接内存溢出-java.lang.OutOfMemoryError: Direct buffer memory。
6. GC超限-java.lang.OutOfMemoryError: GC overhead limit exceeded。
分析OOM问题
查看jvm进程:jps
查看jvm堆内存情况:jmap -heap 进程号
查看堆内存中的对象数目:jmap -histo:live 进程号 | more
查看实时cpu、内存情况:top
查看内存:cat /proc/meminfo
java -jar -Xms128M -Xmx256M -XX:PermSize=128M -XX:MaxPermSize=256M ***.jar
Xms : 堆内存初始大小
Xmx : 堆内存最大值
PermSize : 永久内存初始大小
MaxPermSize : 永久内存最大值
在window环境,配合JDK的 Java VisuaLVM 工具检查堆空间的内存,找到 jdk的bin目录下 jvisualvm.exe 文件,双击打开即可。
内存泄漏实例
Vector vector = new Vector(10);
for (int i = 0; i < 100; i++) {
Object object = new Object();
vector.add(object);
object = null;
}
vector = null;
在上面代码中,我们循环申请Object对象,并将所申请的对象放入一个 Vector 中。如果我们仅仅释放引用本身(object = null;),那么 Vector 仍然引用该对象,所以这个对象对 GC 来说是不可回收的。因此,如果对象加入到Vector 后,还必须从 Vector 中删除,最简单的方法就是将 Vector 对象设置为 null(vector = null;)。
引用对象和未被引用对象和未使用对象:
未被引用对象会被垃圾回收器回收,而被引用的对象却不会。未被引用的对象当然是不再被使用的对象,因为没有对象再引用它。然而无用对象却不全是未被引用对象。其中还有被引用的。就是这种情况导致了内存泄漏。
Java内存泄漏的根本原因是什么呢?长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是因为长生命周期持有它的引用而导致不能被回收,这就是Java中内存泄漏的发生场景。