Java编程思想2

文章目录

  • 1. 构造方法
  • 2. 对象的初始化顺序
    • 1.静态成员初始化
    • 2. 类加载
    • 3. 实例化
    • 总结
  • 3.垃圾回收
    • 1. 标记阶段(Marking)
    • 2. 清除阶段(Sweeping)
    • 3. 垃圾回收的触发时机
    • 4. 分代垃圾回收
    • 5. 垃圾回收算法
      • 1. 标记-清除算法(Mark and Sweep)
      • 2. 复制算法(Copying)
      • 3. 标记-整理算法(Mark and Compact)
      • 4. 分代垃圾回收算法
      • 5. 并发垃圾回收算法


Java编程思想第五章初始化与清理


1. 构造方法

构造方法是在对象创建时执行的特殊方法。它的主要作用是对对象进行初始化。构造方法的特点包括:

  1. 构造方法与类名相同,没有返回类型。
  2. 可以有参数,用于初始化对象的属性。
  3. 在创建对象时自动调用。
class Person {
    String name;
    int age;

    // 构造方法1
    public Person(String n) {
        name = n;
    }

    // 构造方法2
    public Person(String n, int a) {
        name = n;
        age = a;
    }
}


// 创建对象并调用构造方法
Person person1 = new Person("John");

2. 对象的初始化顺序

Java中对象的初始化顺序涉及到静态成员初始化和非静态成员初始化。初始化顺序主要包括以下几个阶段:

1.静态成员初始化

静态成员变量初始化

首先,所有的静态成员变量(包括静态初始化块中的代码)按照在类中的声明顺序进行初始化。这些成员变量在类加载时被初始化,而且只会被初始化一次。

class MyClass {
    static int staticVar1 = initializeStaticVar1();
    static int staticVar2 = 5;

    static {
        // 静态初始化块
        System.out.println("Static Initialization Block");
    }

    static int initializeStaticVar1() {
        return 10;
    }
}

静态成员方法初始化

如果有静态成员方法被调用,它也会在此阶段执行。

class MyClass {
    static int staticVar = initializeStaticVar();

    static int initializeStaticVar() {
        System.out.println("Initializing staticVar");
        return 10;
    }

    static void staticMethod() {
        System.out.println("Static Method");
    }
}

// 调用静态方法
MyClass.staticMethod();

2. 类加载

类加载发生在静态成员初始化之后。在这个阶段,类的字节码被加载到内存中,类的结构被创建,静态成员变量被分配内存。

3. 实例化

实例成员变量初始化

在类加载后,当创建对象实例时,实例成员变量会按照在类中的声明顺序进行初始化。这包括非静态变量和实例初始化块。

class MyClass {
    int instanceVar1 = initializeInstanceVar1();
    int instanceVar2 = 5;

    {
        // 实例初始化块
        System.out.println("Instance Initialization Block");
    }

    int initializeInstanceVar1() {
        return 10;
    }
}

构造方法

最后,构造方法被调用,完成对象的实例化过程。

class MyClass {
    int x;

    // 构造方法
    public MyClass(int x) {
        this.x = x;
    }
}

// 创建对象并调用构造方法
MyClass obj = new MyClass(5);

总结

  1. 类加载时,静态成员变量和静态初始化块按照声明的顺序执行。
  2. 实例化时,实例成员变量和实例初始化块按照声明的顺序执行,然后执行构造方法。

3.垃圾回收

垃圾回收器是Java虚拟机(JVM)的一部分,负责管理和回收不再被程序引用的内存空间,从而防止内存泄漏和提高内存利用效率。垃圾回收器的工作过程可以分为几个阶段:

1. 标记阶段(Marking)

在标记阶段,垃圾回收器遍历对象图,从根节点(如栈帧中的局部变量表、静态变量等)出发,标记所有可达的对象。可达对象是指那些可以通过引用链从根节点访问到的对象。

  1. 根搜索: 从根节点开始遍历对象图,标记所有可达对象。
  2. 引用链跟踪: 沿着引用链继续标记可达对象,直至无法再找到新的可达对象。

2. 清除阶段(Sweeping)

在清除阶段,垃圾回收器清理并释放不再被引用的对象占用的内存空间。

  1. 清理: 遍历整个堆空间,清除未被标记的对象。
  2. 内存回收: 将被清理的内存空间标记为可用,以便下次分配新对象时使用。

在垃圾回收器执行对象回收之前,会调用对象的 finalize() 方法。程序员可以在 finalize() 方法中编写一些清理资源的代码,但是不推荐过度依赖这个方法,因为垃圾回收的执行时机不确定。

class MyClass {
    // 一些类的定义

    // finalize 方法
    protected void finalize() throws Throwable {
        // 执行清理操作
    }
}

3. 垃圾回收的触发时机

垃圾回收并不是周期性地发生,而是在满足一定条件时触发。以下是触发垃圾回收的常见情况:

  1. 空闲时触发: 当系统空闲时,垃圾回收器可能会启动以回收未使用的内存。
  2. 内存不足时触发: 当堆空间中的内存占用达到一定阈值,且无法再分配足够的空间给新对象时,垃圾回收器会触发回收。
  3. 显式调用: 通过调用 System.gc() 或 Runtime.getRuntime().gc() 可以显式触发垃圾回收,但并不保证立即执行。

4. 分代垃圾回收

Java的垃圾回收器通常采用分代回收的策略,将堆空间划分为不同的代,主要包括年轻代(Young Generation)和老年代(Old Generation)。

  1. 年轻代: 用于存放新创建的对象。在年轻代中,采用复制算法,将存活对象从一块复制到另一块,然后清理当前使用的块。
  2. 老年代: 用于存放存活时间较长的对象。在老年代中,采用标记-清除或标记-整理算法进行垃圾回收。

5. 垃圾回收算法

1. 标记-清除算法(Mark and Sweep)

  • 标记阶段: 通过根节点(如栈帧中的局部变量表、静态变量等)遍历对象图,标记所有可达对象。
  • 清除阶段: 遍历整个堆,清除未标记的对象,释放其内存空间。

优点

  • 简单,易于实现。

缺点

  • 内存碎片化问题:清除阶段会导致内存出现碎片,可能影响分配大对象的性能。
  • 暂停时间较长:标记和清除两个阶段会导致垃圾回收期间应用程序停顿。

2. 复制算法(Copying)

  • 将堆空间分为两块,每次只使用其中一块。
  • 在垃圾回收时,将存活对象从一块复制到另一块,然后清除当前使用的块。

优点:

  • 解决了内存碎片问题,所有存活对象都被紧凑地存储在一块中。
  • 暂停时间较短。

缺点:

  • 需要额外的空间,只能利用一半的堆空间。

3. 标记-整理算法(Mark and Compact)

  • 类似于标记-清除算法,但在清除阶段,会将存活对象向一端移动,然后清理掉边界之外的空间。

优点:

  • 解决了内存碎片问题。
  • 暂停时间相对较短。

缺点:

  • 移动存活对象需要额外的时间。

4. 分代垃圾回收算法

  • 将堆空间分为年轻代和老年代两部分。
  • 年轻代用于存放新创建的对象,老年代用于存放存活时间较长的对象。

优点:

  • 针对不同对象生命周期的分代策略,提高了垃圾回收的效率。

缺点:

  • 需要维护多个代的空间划分。

5. 并发垃圾回收算法

  • 针对减小垃圾回收对应用程序的影响,允许垃圾回收与应用程序同时进行。

例子:

  • CMS(Concurrent Mark-Sweep):并发标记和清除算法,减小暂停时间。
  • G1(Garbage-First):分代和并发的垃圾回收器,通过划分堆空间为多个小块,以及采用复制和整理策略,提高了吞吐量和降低了暂停时间。

每种垃圾回收算法都有其适用的场景和优缺点,Java虚拟机根据不同的需求选择不同的垃圾回收算法,或者通过参数配置来调整垃圾回收器的行为。

你可能感兴趣的:(Java编程思想,java,开发语言,jvm)