瘟疫青年

JAVA的垃圾回收策略

Word count: 1.2kReading time: 4 min
2018/05/17 Share

前言

创建了一个对象,就意味着或早或晚,该对象都是需要 被释放掉的,只不过这个时间有长有短,对象从被new出来到被垃圾回收器回收,就是一个生命周期的完整过程,java的垃圾回收机制可以做到自动决定哪些对象是无用的从而被回收掉,无需使用者担心,但是不健壮的java代码会影响到回收算法对无效对象的识别,从而影响对象的生命周期,导致无法回收。为了弄清楚java的垃圾回收机制,有必要先搞懂下面这些概念。

java程序的生存空间: 堆与栈

  • 堆:实例变量(成员变量)与对象的生存空间
  • 栈:方法调用与局部变量的生存空间

    注1:实例变量生命在对象内部,而不是方法内,塔代表每一个独立对象的“字段”,是存储在对象中的。

注2:局部变量生命在方法中,他们是暂时的,生命周期只限于方法被放入栈上的时间,也就是方法执行到结束的过程。

注3:方法的调用过程,是伴随方法栈入栈出栈的过程的,方法被调用,一个对应的方法堆栈块也就被放置到栈顶,这个堆栈块里除了存放局部变量和方法参数之外,还会存放方法的执行状态,包括方法执行的行数,当方法执行完毕之后,该方法堆栈块便会出栈。

如果是这样

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args){
foo1();
}

void bar(){}

void foo2(){}

void foo1(){
foo2();
}

方法foo1 调用了foo2 执行到调用时,会将foo2放在foo1()的栈顶上,foo1被压下去。

注4:非primitive(注5)的变量都只是对对象的引用而已,所以所有的局部变量,变量本身都是存放在方法栈空间的,当所指向的对象被实例化了,对象存放在堆空间。

注5:java的变量类型分为 primitive数据类型和 引用类型,primitive 主数据类型用来保存基本类型的值,包括整数、布尔和浮点数等,而对象引用保存的是对象的引用。

注6: 不管是实例变量还是局部变量,对象本身都是存放在堆上的

对象的创建 三部曲:声明、创建、赋值

1
2
3
Duck duck   // 1.创建出新的引用变量duck给Duck类型
= //3. 赋值该对象给引用变量
new Duck(); //2. 创建该对象实例

调用new 方法,便创建了一个duck实例,这其中的过程其实是调用了类的构造方法。

注意 对象构造方法会先与对象实例被赋值给引用对象之前就执行。

1
2
3
4
5
6
7
8
9
10
11
public class People{
public People(){
System.out.println('people');
}
}

public class Person{
public static void main(){
People p = new People();
}
}

会打印出people的log

对象的声明周期

对象的生命周期是看对象的引用。如果还有引用,对象继续存活在堆上,如果没有引用了,对象就会被垃圾回收器回收。
所以==对象的声明周期 要看引用变量的声明周期==,而引用变量的声明周期,又要看它是局部变量还是成员变量。

  • 局部变量: 与方法声明周期同步,只活在该方法内,方法执行完毕,对象立即被释放,对其他程序和方法不可见。
  • 成员变量: 与对象声明周期同步。如果对象活着,该成员变量也活着。

    关于局部变量,这里需要讲两个概念

    Life

    对象的堆栈块还在栈内,方法还没执行完,就还活着。活到方法执行完结束。

Scope

局部变量的范围,只存在声明它的方法内,如果该方法调用了其他方法,则该变量仍然存活,只不过在执行调用方法的时候,该变量不在它的范围而已。

只要方法还没执行完,对象就不会死,但只有方法在栈顶,对象才是可用的。

变量的生命周期如何影响对象的生命周期?

只要有活的引用,对象会一直活着,如果对某个对象的引用不在它的范围内,但该引用变量还是活的,则该对象也会活着,呆在堆内存中。如果对该对象的唯一引用没有了,对象便会回收

三种方法释放对象引用:

1
2
3
4
5
6
7
8
9
10
// 方法执行完,引用便释放了
void go(){
People p = new People();
}
// 引用被赋值到别处
People p = new People();
p = new People(); //第一个对象会在此时被释放
// 直接置空
People p = new People();
p =null;

—待续 5.17 00:51

CATALOG
  1. 1. 前言
  2. 2. java程序的生存空间: 堆与栈
  3. 3. 对象的创建 三部曲:声明、创建、赋值
  4. 4. 对象的声明周期
    1. 4.0.1. 关于局部变量,这里需要讲两个概念
  5. 4.1. Life
  6. 4.2. Scope
  • 5. 变量的生命周期如何影响对象的生命周期?