Java9以后的垃圾回收的具體用法
1: finalize() 方法
finallize() 方法是Object類的方法, 用于在類被GC回收時(shí) 做一些處理操作, 但是JVM并不能保證finalize(0 ) 方法一定被執(zhí)行,
由于finalize()方法的調(diào)用時(shí)機(jī)具有不確定性,從一個(gè)對(duì)象變得不可到達(dá)開始,到finalize()方法被執(zhí)行,所花費(fèi)的時(shí)間這段時(shí)間是任意長的。我們并不能依賴finalize()方法能及時(shí)的回收占用的資源,可能出現(xiàn)的情況是在我們耗盡資源之前,gc卻仍未觸發(fā),因而通常的做法是提供顯示的close()方法供客戶端手動(dòng)調(diào)用
所以一般不建議使用finalize 方法, JDK9 開始已久被廢除
- 總結(jié)缺點(diǎn)
1: finalize機(jī)制本身就是存在問題的。
2:finalize機(jī)制可能會(huì)導(dǎo)致性能問題,死鎖和線程掛起。
3:finalize中的錯(cuò)誤可能導(dǎo)致內(nèi)存泄漏;如果不在需要時(shí),也沒有辦法取消垃圾回收;并且沒有指定不同執(zhí)行finalize對(duì)象的執(zhí)行順序。此外,沒有辦法保證finlize的執(zhí)行時(shí)間。
遇到這些情況,對(duì)象調(diào)用finalize方法只有被無限期延后
-觀察finalize方法延長類生命周期
class User{
public static User user = null;
@Override
protected void finalize() throws Throwable {
System.out.println("User-->finalize()");
user = this;
}
}
public class FinalizerTest {
public static void main(String[] args) throws InterruptedException {
User user = new User();
user = null;
System.gc();
Thread.sleep(1000);
user = User.user;
System.out.println(user != null);//true
user = null;
System.gc();
Thread.sleep(1000);
System.out.println(user != null);//false
}
}
- JDk9 以前的垃圾回收代碼
public class Finalizer {
@Override
protected void finalize() throws Throwable {
System.out.println("Finalizer-->finalize()");
}
public static void main(String[] args) {
Finalizer f = new Finalizer();
f = null;
System.gc();//手動(dòng)請(qǐng)求gc
}
}
//輸出 Finalizer-->finalize()
2:Cleaner類的使用
簡介:
在Java9 以后 提供了最終類Clear來代替實(shí)現(xiàn),下面看一下官方例子
package Thread;
import java.lang.ref.Cleaner;
public class CleaningExample implements AutoCloseable{
private final static Cleaner CLEANER=Cleaner.create();// 創(chuàng)建者模式創(chuàng)建對(duì)象
static class State implements Runnable{ // 清理對(duì)象 下面說
State() {
System.out.println("init");
}
@Override
public void run() {
System.out.println("close");
}
}
private final State state;
private final Cleaner.Cleanable cleanable; // clearner 中的接口 實(shí)現(xiàn)唯一的清理方法
public CleaningExample() {
super();
this.state = new State();
this.cleanable=CLEANER.register(this, state); // 注冊(cè)清理容器中 并且需要清理對(duì)象的引用
}
@Override
public void close() throws Exception {
cleanable.clean(); //進(jìn)行清理操作
}
public static void main(String[] args) {
while(true) {
new CleaningExample();
}
}
}
上面 看出:
Cleaner 是最終類 不能被重寫, 內(nèi)部方法基本以靜態(tài)方法提供 掌握例子上面的方法即可
重點(diǎn)指出
static class State implements Runnable
如果直接在類中直接定義實(shí)現(xiàn), 必須提供一個(gè)靜態(tài)內(nèi)部類 (強(qiáng)制),否者不能進(jìn)行回收 原因(: 普通內(nèi)部類 局部內(nèi)部類 對(duì)于外部類有依賴(引用),無法真正實(shí)現(xiàn)內(nèi)存的釋放 )
可以選擇直接定義外部類 (較為復(fù)雜,需要傳遞清理引用 Cleanable)
什么時(shí)候被回收?
* 1. 注冊(cè)的Object處于幻象引用狀態(tài)
* 2. 顯式調(diào)用 clean 方法
實(shí)際例子(模版)
public class CleaningExample extends Thread implements AutoCloseable {
private final static Cleaner CLEANER = Cleaner.create();
private final State state;
private final Cleaner.Cleanable cleanable;
public CleaningExample() {
this.state = new State();
this.cleanable = CLEANER.register(this, state);
}
@Override
public void close() throws Exception {
cleanable.clean();
}
@SuppressWarnings("resource")
public static void main(String[] args) {
while (true) {
CleaningExample example = new CleaningExample();
}
}
// 模擬業(yè)務(wù)請(qǐng)求
@Override
public void run() {
System.out.println("數(shù)據(jù)庫 海量 查詢請(qǐng)求 ................");
}
// 清理模版
class State implements Runnable {
State() {
System.out.println("<--- init --->");
}
@Override
public void run() {
System.out.println("<--- close --->");
}
}
}
實(shí)現(xiàn)基礎(chǔ)
/** * Heads of a CleanableList for each reference type. */ final PhantomCleanable<?> phantomCleanableList; final WeakCleanable<?> weakCleanableList; final SoftCleanable<?> softCleanableList; // The ReferenceQueue of pending cleaning actions final ReferenceQueue<Object> queue;
在CleanerImpl 類進(jìn)行clearner類的最終實(shí)現(xiàn),看以看到定義的這些個(gè)字段,基本上明確了 他的基本原理
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
淺析SpringBoot微服務(wù)中異步調(diào)用數(shù)據(jù)提交數(shù)據(jù)庫的問題
這篇文章主要介紹了SpringBoot微服務(wù)中異步調(diào)用數(shù)據(jù)提交數(shù)據(jù)庫的問題,今天本文涉及到的知識(shí)點(diǎn)不難,都是很簡單的crud操作,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
idea集成shell運(yùn)行環(huán)境以及shell輸出中文亂碼的解決
這篇文章主要介紹了idea集成shell運(yùn)行環(huán)境以及shell輸出中文亂碼的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Java service層獲取HttpServletRequest工具類的方法
今天小編就為大家分享一篇關(guān)于Java service層獲取HttpServletRequest工具類的方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12
Java如何找出數(shù)組中重復(fù)的數(shù)字
這篇文章主要為大家詳細(xì)介紹了Java如何找出數(shù)組中重復(fù)的數(shù)字,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08
java synchronized加載加鎖-線程可重入詳解及實(shí)例代碼
這篇文章主要介紹了java synchronized加載加鎖-線程可重入詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02
java自帶的MessageDigest實(shí)現(xiàn)文本的md5加密算法
這篇文章主要介紹了java自帶的MessageDigest實(shí)現(xiàn)文本的md5加密算法,需要的朋友可以參考下2015-12-12
redis防止重復(fù)提交的實(shí)現(xiàn)示例
在開發(fā)中我們都需要處理重復(fù)提交的問題,本文主要介紹了redis防止重復(fù)提交的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06
javabean servlet jsp實(shí)現(xiàn)分頁功能代碼解析
這篇文章主要為大家詳細(xì)解析了javabean servlet jsp實(shí)現(xiàn)分頁功能代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09

