-
很多开发者都知道,在面试的时候会经常被问到内存泄露和内存溢出的问题。
1.内存溢出(Out Of Memory,简称 OOM),通俗理解就是内存不够,即内存占用超出内存的空间大小。
2.内存泄漏(Memory Leak),简单理解就是内存使用完毕之后本该垃圾回收却未被回收。
-
在正式了解内存泄露之前,首先来简单回顾一下 Java 内存分配策略。
Java 程序运行时的内存分配策略有三种,分别是静态分配、栈式分配、堆式分配,对应的主要内存空间分别是静态存储区(也称方法区)、栈区、堆区。
1.静态存储区(方法区)
主要存放静态数据、全局 static 数据和常量。这块内存在程序编译时就已经分配好,并且在程序整个运行期间都存在。
2.栈区
当方法被执行时,方法体内的局部变量都在栈上创建,并在方法执行结束时这些局部变量所持有的内存将会自动被释放。因为栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
3.堆区
又称动态内存分配,通常就是指在程序运行时直接 new 出来的内存。这部分内存在不使用时将会由 Java 垃圾回收器来负责回收。
-
在 Java 中,内存的分配是由程序完成的,而内存的释放是由 GC 完成的,这种方式大大简化了程序员的工作,但同时却加重了 JVM 的工作,这也是 Java 程序运行速度较慢的原因之一。GC 为了能够正确释放对象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,监视对象的状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不再被引用。
END