2010-05-28 71 views
35

運行Java 1.6(1.6.0_03-b05)應用程序時,我添加了-XX:+PrintCompilation標誌。在某些方法的輸出中,尤其是我知道的那些方法中的一些會被調用很多,我會看到文本made not entrantmade zombiejava PrintCompilation輸出:「made not entrant」和「made zombie」的含義

這些是什麼意思?最好的猜測是,在重新編譯該方法或具有更大優化的依賴性之前,這是一個反編譯步驟。真的嗎?爲什麼「殭屍」和「進入者」?

例,與這些線之間相當多的時間:

[... near the beginning] 
42  jsr166y.LinkedTransferQueue::xfer (294 bytes) 

[... much later] 
42 made not entrant jsr166y.LinkedTransferQueue::xfer (294 bytes) 
--- n sun.misc.Unsafe::compareAndSwapObject 
170  jsr166y.LinkedTransferQueue::xfer (294 bytes) 
170 made not entrant jsr166y.LinkedTransferQueue::xfer (294 bytes) 
    4%  jsr166y.LinkedTransferQueue::xfer @ 29 (294 bytes) 
171  jsr166y.LinkedTransferQueue::xfer (294 bytes) 

[... even later] 
42 made zombie jsr166y.LinkedTransferQueue::xfer (294 bytes) 
170 made zombie jsr166y.LinkedTransferQueue::xfer (294 bytes) 
171 made not entrant jsr166y.LinkedTransferQueue::xfer (294 bytes) 
172  jsr166y.LinkedTransferQueue::xfer (294 bytes) 

[... no further logs] 

回答

22

我已經在my blog上收集了一些關於此的信息。懸崖點擊評論我發現說:

殭屍方法的方法,其代碼被加載類無效。通常,服務器編譯器會對非最終方法的決策進行積極的內聯。只要內聯方法從不被覆蓋,代碼就是正確的。當一個子類被加載並且該方法被覆蓋時,編譯後的代碼將被打破以後的所有調用。代碼被聲明爲「不可進入」(沒有未來呼叫者到破碎的代碼),但有時現有的呼叫者可以繼續使用代碼。在內聯的情況下,這還不夠好;現有的調用者的堆棧框架在從嵌套調用返回代碼時(或者只是在代碼中運行時)會「去優化」。當沒有更多的堆棧幀將PC保存到破損的代碼中時,它被聲明爲「殭屍」 - 一旦GC接近它,準備移除。

+7

Kris Mok給JodaStephen寫了一封回覆,現在他的博客已經鏈接了,並且在對-XX:+ PrintCompilation的描述中更加完整。這裏的鏈接: https://gist.github.com/1165804#file_notes.md – Blaisorblade 2011-11-16 18:15:09

9

這絕對不是我的專長的領域,但我很感興趣,所以沒有一點挖的。

您可能會感興趣的幾個鏈接:OpenJDK:nmethod.cppOpenJDK:nmethod.hpp

nmethod.hpp一個摘錄:

// Make the nmethod non entrant. The nmethod will continue to be 
// alive. It is used when an uncommon trap happens. Returns true 
// if this thread changed the state of the nmethod or false if 
// another thread performed the transition. 
bool make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); } 
//... 

就像一個起點。

+0

這是一個有用的開始,謝謝。我越查看代碼,我發現更多的熱點詞彙我不知道!那麼我們是否認爲「not_entrant」僅僅意味着「不要再次執行這個已編譯的代碼,需要先取消/重新編譯」? 另一鏈接:請參閱http://www.google.com/codesearch/p?hl=en#aRIt9pqzOVI/src/share/vm/oops/methodOop.cpp的第536行 – 2010-06-03 13:33:21

+3

鑑於「參與者」的含義,我的*猜測*會是它標記編譯的方法不再被*輸入*(儘管一些線程可能仍然在其中),而殭屍意味着它沒有進一步的使用並且可以被丟棄。就像結賬櫃檯可能宣佈它不接受新客戶(非參與者),但仍然必須服務排隊的客戶,然後關閉殭屍(殭屍)。但這只是一個猜測。 – 2010-06-03 14:22:36

+0

不錯的比喻:p – 2010-06-03 14:25:30

1

Here is a GistPrintCompilation上有難以置信的信息量。具體而言,它說:

當去優化發生時,如果決定使違規的nmethod無效,它將首先被「取消進入」。然後,當NMethodSweeper發現堆棧上不再激活它時,它就是「製造殭屍」。