JVM(三) 垃圾回收

一、自动垃圾回收

1.1 C/C++的内存管理 

  1. 在C/C++这类没有自动垃圾回收机制的语言中,一个对象如果不再使用,需要手动释放,否则就会出现内存泄漏。我们称这种释放对象的过程为垃圾回收,而需要程序员编写代码进行回收的方式为手动回收。 
  2. 内存泄漏指的是不再使用的对象在系统中未被回收,泄漏的积累可能会导致内存溢出。

1.2 Java的内存管理

Java中为了简化对象的释放,引入了自动的垃圾回收(Garbage Collection简称GC)机制。通过垃圾回收器来对不再使用的对象完成自动的回收,垃圾回收器主要负责对上的内存进行回收。其他很多现代语言比如C#、Python、Go都拥有自己的垃圾回收器。

P5

 1.3 垃圾回收的对比

1.3.1 自动垃圾回收

自动根据对象是否使用由虚拟机来回收对象

 优点:降低程序员实现难度、降低对象回收bug的可能性

 缺点:程序员无法控制内存回收的及时性

 1.3.2 手动垃圾回收

由程序员编程实现对象的删除

优点:回收及时性高,由程序员把控回收的时机 

缺点:编写不当容易出现悬空指针、重复释放、内存泄漏等问题

 二、方法区的回收

线程不共享的部分,都是伴随着线程的创建而创建,线程的销毁而销毁。而方法的栈帧在执行完方法之后就会 自动弹出栈并释放掉对应的内存。

方法区中能回收的内容主要就是不再使用的类。

判定一个类可以被卸载。需要同时满足下面三个条件:

1、此类所有实例对象都已经被回收,在堆中不存在任何该类的实例对象以及子类对象

2、加载该类的类加载器已经被回收

3、该类对应的 java.lang.Class 对象没有在任何地方被引用

 如果需要手动触发垃圾回收,可以调用System.gc()方法。

语法: System.gc()

注意事项: 调用System.gc()方法并不一定会立即回收垃圾,仅仅是向Java虚拟机发送一个垃圾回收的请求,具体是否需要 执行垃圾回收Java虚拟机会自行判断。

方法区中的类的卸载是相对比较复杂的操作,因为方法区主要存放的是类的元数据信息和静态变量,所以在卸载一个类时需要确保不会影响到其他正在运行的类和静态数据的引用。因此,方法区的类卸载一般较少发生,在一些特定的场景下才会进行卸载操作。

 三、堆回收

Java中的对象是否能被回收,是根据对象是否被引用来决定的。如果对象被引用了,说明

你可能感兴趣的:(jvm)