第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

JVM 何時(shí)將成員變量引用存儲(chǔ)在堆棧上?

JVM 何時(shí)將成員變量引用存儲(chǔ)在堆棧上?

猛跑小豬 2022-06-04 10:39:19
我正在閱讀Java SE 規(guī)范的第 12.6.1 節(jié),它說(shuō):可以設(shè)計(jì)優(yōu)化程序的轉(zhuǎn)換,將可到達(dá)的對(duì)象的數(shù)量減少到比那些天真地認(rèn)為是可到達(dá)的要少。例如,Java 編譯器或代碼生成器可能會(huì)選擇將不再使用的變量或參數(shù)設(shè)置為 null,以使此類(lèi)對(duì)象的存儲(chǔ)空間可能更快地被回收。如果對(duì)象字段中的值存儲(chǔ)在寄存器中,則會(huì)出現(xiàn)另一個(gè)示例。然后程序可能會(huì)訪問(wèn)寄存器而不是對(duì)象,并且永遠(yuǎn)不會(huì)再次訪問(wèn)對(duì)象。這意味著該對(duì)象是垃圾。請(qǐng)注意,僅當(dāng)引用在堆棧上而不是存儲(chǔ)在堆中時(shí)才允許進(jìn)行這種優(yōu)化。相關(guān)代碼為:class Foo {    private final Object finalizerGuardian = new Object() {        protected void finalize() throws Throwable {            /* finalize outer Foo object */        }    }} 我的問(wèn)題是哪種 JVM 會(huì)將 finalizerGuardian 存儲(chǔ)在堆棧而不是堆中,為什么?
查看完整描述

2 回答

?
湖上湖

TA貢獻(xiàn)2003條經(jīng)驗(yàn) 獲得超2個(gè)贊

代碼示例用于說(shuō)明引用文本的最后一句話,“請(qǐng)注意,僅當(dāng)引用在堆棧上而不是存儲(chǔ)在堆中時(shí)才允許進(jìn)行這種優(yōu)化”,您將其從解釋中扯下來(lái)有點(diǎn)奇怪文本:


例如,考慮Finalizer Guardian模式:


 class Foo {

     private final Object finalizerGuardian = new Object() {

         protected void finalize() throws Throwable {

             /* finalize outer Foo object */

         }

     }

 } 

super.finalize如果子類(lèi)覆蓋并且finalize未顯式調(diào)用super.finalize.


如果允許對(duì)存儲(chǔ)在堆上的引用進(jìn)行這些優(yōu)化,那么 Java 編譯器可以檢測(cè)到該finalizerGuardian字段從未被讀取,將其清空,立即收集對(duì)象,并盡早調(diào)用終結(jié)器。這與意圖背道而馳:程序員可能想在 Foo 實(shí)例變得無(wú)法訪問(wèn)時(shí)調(diào)用 Foo 終結(jié)器。因此,這種轉(zhuǎn)換是不合法的:只要外部類(lèi)對(duì)象可訪問(wèn),內(nèi)部類(lèi)對(duì)象就應(yīng)該是可訪問(wèn)的。


所以代碼示例說(shuō)明了一個(gè)限制。規(guī)范中提到的“優(yōu)化轉(zhuǎn)換”包括在逃逸分析證明對(duì)象是純本地的之后應(yīng)用的對(duì)象標(biāo)量化,換句話說(shuō),優(yōu)化下的代碼跨越對(duì)象的整個(gè)生命周期。


但它不需要這樣的本地對(duì)象。正如規(guī)范已經(jīng)提到的,優(yōu)化的代碼可以將對(duì)象的字段保留在 CPU 寄存器中,而無(wú)需重新讀取它們,因此,不再需要保留對(duì)象引用。同樣,仍然在范圍內(nèi)的引用變量可能未被使用。如果該引用是對(duì)某個(gè)對(duì)象的唯一引用,則將其從優(yōu)化代碼中刪除允許更早地進(jìn)行垃圾回收。


這兩種情況仍然允許Foo實(shí)例被更早地消除或收集。這反過(guò)來(lái)將允許較早地收集 . 引用的對(duì)象(不再是)finalizerGuardian。但這并不能抵消這種限制的意圖。規(guī)范將優(yōu)化限制為不允許內(nèi)部對(duì)象早于外部對(duì)象被收集,但將兩者收集在一起沒(méi)有問(wèn)題,包括早于天真的預(yù)期。


通常,任意大的對(duì)象圖可能會(huì)在單個(gè)垃圾收集周期中被收集,可能比天真預(yù)期的要早,甚至完全被優(yōu)化掉。


查看完整回答
反對(duì) 回復(fù) 2022-06-04
?
largeQ

TA貢獻(xiàn)2039條經(jīng)驗(yàn) 獲得超8個(gè)贊

這種優(yōu)化(逃逸分析)的一個(gè)經(jīng)典例子是一個(gè)帶有Point類(lèi)的計(jì)算:



class Point {

    double x;

    double y;


    public Point(final double x, final double y) {

        this.x = x;

        this.y = y;

    }


    double length() {

        return Math.sqrt(x * x + y * y);

    }


    static double calc() {

        double result = 0;

        for (int i = 0; i < 100; i++) {

            // this allocation will be optimized 

            Point point = new Point(i, i);

            result += point.length();

        }

        return result;

    }

}

內(nèi)聯(lián)后就new不需要了,因?yàn)槲覀兛梢詫⑺凶侄翁崛〉骄植孔兞恐校?/p>


Point point = new Point(i, i);

double x = point.x;

double y = point.y;

result += Math.sqrt(x * x + y * y);

->


Point point = new Point(i, i);

double x = i;

double y = i;

result += Math.sqrt(x * x + y * y);

現(xiàn)在很明顯這new Point(i, i)是沒(méi)用的,JIT 只是刪除了這一行。


請(qǐng)注意,分配是在堆棧上,即在局部變量中。如果它在一個(gè)字段中,我們將無(wú)法進(jìn)行優(yōu)化,因?yàn)樗鎯?chǔ)在堆中。它是如何工作的。


關(guān)于您的代碼被剪斷:finalizerGuardian將始終在字段中(存儲(chǔ)在堆中),而 JVM 對(duì)此分配無(wú)能為力。此外,如果Point上面示例中的類(lèi)包含此類(lèi)字段,我認(rèn)為轉(zhuǎn)義分析無(wú)法刪除分配,因?yàn)樗赡軙?huì)改變?cè)夹袨椤?/p>


查看完整回答
反對(duì) 回復(fù) 2022-06-04
  • 2 回答
  • 0 關(guān)注
  • 122 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)