mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-25 02:27:10 +08:00
[docs uodate]添加了对 finalize 方法的简单介绍
This commit is contained in:
parent
39c8980e46
commit
0257a01f32
@ -71,6 +71,7 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆(G
|
||||
接下来我们提供一个调试脚本来测试这个过程。
|
||||
|
||||
**调试代码参数如下**
|
||||
|
||||
```
|
||||
-verbose:gc
|
||||
-Xmx200M
|
||||
@ -85,7 +86,9 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆(G
|
||||
-XX:+UseConcMarkSweepGC
|
||||
-XX:+UseParNewGC
|
||||
```
|
||||
|
||||
**示例代码如下:**
|
||||
|
||||
```java
|
||||
/*
|
||||
* 本实例用于java GC以后,新生代survivor区域的变化,以及晋升到老年代的时间和方式的测试代码。需要自行分步注释不需要的代码进行反复测试对比
|
||||
@ -133,6 +136,7 @@ public class JavaGcTest {
|
||||
```
|
||||
|
||||
注意:如下输出结果中老年代的信息为 `concurrent mark-sweep generation` 和以前版本略有不同。另外,还列出了某次 GC 后是否重新生成了 threshold,以及各个年龄占用空间的大小。
|
||||
|
||||
```bash
|
||||
2021-07-01T10:41:32.257+0800: [GC (Allocation Failure) 2021-07-01T10:41:32.257+0800: [ParNew
|
||||
Desired survivor size 3145728 bytes, new threshold 1 (max 3)
|
||||
@ -150,6 +154,7 @@ Heap
|
||||
Metaspace used 153K, capacity 2280K, committed 2368K, reserved 4480K
|
||||
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 1.1 对象优先在 eden 区分配
|
||||
@ -366,10 +371,17 @@ JDK1.2 以后,Java 对引用的概念进行了扩充,将引用分为强引
|
||||
|
||||
### 2.4 不可达的对象并非“非死不可”
|
||||
|
||||
即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对象死亡,至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize 方法。当对象没有覆盖 finalize 方法,或 finalize 方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。
|
||||
即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对象死亡,至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 `finalize` 方法。当对象没有覆盖 `finalize` 方法,或 `finalize` 方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。
|
||||
|
||||
被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关联,否则就会被真的回收。
|
||||
|
||||
> `Object` 类中的 `finalize` 方法一直被认为是一个糟糕的设计,成为了 Java 语言的负担,影响了 Java 语言的安全和 GC 的性能。JDK9 版本及后续版本中各个类中的 `finalize` 方法会被逐渐弃用移除。忘掉它的存在吧!
|
||||
>
|
||||
> 参考:
|
||||
>
|
||||
> - [JEP 421: Deprecate Finalization for Removal](https://openjdk.java.net/jeps/421)
|
||||
> - [是时候忘掉 finalize 方法了](https://mp.weixin.qq.com/s/LW-paZAMD08DP_3-XCUxmg)
|
||||
|
||||
### 2.5 如何判断一个常量是废弃常量?
|
||||
|
||||
运行时常量池主要回收的是废弃的常量。那么,我们如何判断一个常量是废弃常量呢?
|
||||
|
@ -246,7 +246,7 @@ JVM内存会划分为堆内存和非堆内存,堆内存中也会划分为**年
|
||||
|
||||
finalize()是Object类的一个方法、一个对象的finalize()方法只会被系统自动调用一次,经过finalize()方法逃脱死亡的对象,第二次不会再调用。
|
||||
|
||||
补充一句:并不提倡在程序中调用finalize()来进行自救。建议忘掉Java程序中该方法的存在。因为它执行的时间不确定,甚至是否被执行也不确定(Java程序的不正常退出),而且运行代价高昂,无法保证各个对象的调用顺序(甚至有不同线程中调用)。在Java9中已经被标记为 **deprecated** ,且java.lang.ref.Cleaner(也就是强、软、弱、幻象引用的那一套)中已经逐步替换掉它,会比finalize来的更加的轻量及可靠。
|
||||
补充一句:并不提倡在程序中调用finalize()来进行自救。建议忘掉Java程序中该方法的存在。因为它执行的时间不确定,甚至是否被执行也不确定(Java程序的不正常退出),而且运行代价高昂,无法保证各个对象的调用顺序(甚至有不同线程中调用)。在Java9中已经被标记为 **deprecated** ,且 `java.lang.ref.Cleaner`(也就是强、软、弱、幻象引用的那一套)中已经逐步替换掉它,会比 `finalize` 来的更加的轻量及可靠。
|
||||
|
||||

|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user