什么是内存泄漏?
- 该被释放的对象没有释放,一直被某个或某些实例所持有却不再被使用导致 GC 不能回收。
- 多次的内存泄漏的叠加,将导致内存溢出。
示例
public class Simple { public static void main(String args[]){ Object object1 = new Object();//obj1 Object object2 = new Object();//obj2 object2 = object1; //...此时,obj2是可以被清理的 } }
Java的内存分配策略
- 栈区(每个线程有自己的栈区域)
当方法被执行时,方法体内的局部变量(其中包括基础数据类型、对象的引用)都在栈上创建,并在方法执行结束时这些局部变量所持有的内存将会自动被释放。因为栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 - 堆区
又称动态内存分配,通常存放程序在运行时直接 new 出来的对象(包括这个对象其中的所有成员变量)和数组,也就是对象的实例。这部分内存在不使用时将会由 Java 垃圾回收器来负责回收。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,这个特殊的变量就是我们上面说的引用变量。我们可以通过这个引用变量来访问堆中的对象或者数组。 - 静态存储区(方法区)
主要存放静态数据、全局 static 数据和常量。这块内存在程序编译时就已经分配好,并且在程序整个运行期间都存在。 示例
public class Sample { int a=0; Sample sample1 = new Sample(); public void method() { int b=1; Sample sample2 = new Sample(); } }
在另外一个类中new了一个Sample对象,那么这个时候那个对象中a和sample1值在堆中,b和sample2在栈中(因为生命周期随着方法的结束而结束),sample2指向的对象【倒数第三行的new Sample()】在堆中
- 栈区(每个线程有自己的栈区域)
常见内存泄漏
生命周期长的对象引用了生命周期短的对象。
Java中的内存泄漏
最新推荐文章于 2024-09-05 14:32:47 发布