簡體   English   中英

Java銷毀變量

[英]Java Destruction of Variables

最近有一位開發人員問我這個問題,但無法提供答案...

在Java中,如何/何時處置變量? 是嗎

假設我們有一個run()方法,每秒調用50-75次(非常簡化的示例)...

public void run() {
    long lastTime = System.nanoTime();
    double unprocessed = 0;
    int ticks = 0;
    int frames = 0;
    double nsPerTick = 1000000000.0 / 60.0;
    long now = System.nanoTime();
    unprocessed += (now - lastTime) / nsPerTick;
    lastTime = now;

    ticks++;
    tick();
    unprocessed -= 1;
}

將這些變量(lastTime,未處理,滴答聲等)帶入更高的范圍會否使程序更好/更有效地運行-到每秒不會創建和使用多次的地方?

由於這些變量是在stack中創建的,因此不會給您帶來任何性能改進。

閱讀本文以獲得有關Java中對象銷毀的更多信息:

Java中使用哪種方法銷毀對象

Java使用垃圾回收器 ,因此未使用的對象將被自動處理。 在您的示例中,您僅使用局部變量,它們在堆棧中分配,並且速度非常快(這里不涉及垃圾收集)。 將這些變量移至外部函數(“范圍較高”)將無濟於事。

在Java中,如何/何時處置變量? 是嗎

首先,讓我們弄清楚。 在Java中,有些東西叫做變量,有些東西叫做對象。 變量和對象不是一回事。

Java中的變量始終是其他內容的一部分:

  • 局部變量是方法調用狀態的一部分。 超出范圍時將被丟棄。 通常意味着方法調用結束並且方法調用的堆棧框架從調用堆棧彈出。

  • 實例變量(或字段或屬性)是對象的一部分。 當對象被丟棄時,它將被丟棄。

  • 靜態變量(或類變量)是一類的一部分,並且將僅獲得設置如果類被卸載的。

在您的示例中,所有變量都是局部變量,並且在對run()方法的當前調用返回(或由於異常而終止run()時將被“處置”。

將這些變量(lastTime,未處理,滴答聲等)帶入更高的范圍會否使程序更好/更有效地運行-到每秒不會創建和使用多次的地方?

這沒有幫助。 創建或局部變量的處置的增量成本是零1。 並且使用局部變量的成本(如果有的話) 使用實例變量的成本要低。 唯一的成本可能是初始化它,但是無論如何,您都會產生該成本。 例如,在每個方法調用上重新初始化實例變量。

事實上,把局部變量為實例變量實際上可能是一件壞事。 這意味着該方法現在使用對象變量來表示其狀態,從而使其不可重入。 (目前尚不清楚這是否重要。這取決於是否以可重入的方式使用run()方法……通常情況並非如此。)


1-有點過分簡化了。 如果您有足夠多的局部變量和/或深度遞歸的方法,則可能需要使用比正常線程堆棧大的大小。 那額外的內存使用將是一個代價。

這個問題的答案取決於Java的Garbage集合,該集合具有一個較小的切片,稱為“ nursery gc”,該切片被頻繁調用且不會導致jvm停止。 所有局部變量都轉到該托兒所gc。 該方法執行完成時; 所有這些變量都符合GC條件; 並在調用托兒所gc時將其刪除。

回答您的問題是否將這些變量移出運行方法會更好。 盡管JVM在每個發行版中都變得越來越聰明。 創建對象對性能的影響較小。 但是我仍然感到即使影響很小。 我覺得使對象具有全局性沒有害處。

盡管在這種情況下,所有變量都是原始變量。 它不會產生任何影響。

ID取決於JVM運行模式和JVM版本。

但是大多數JVM版本將執行以下操作:

當JVM在-client模式下運行時,代碼將逐行運行。

但是,當JVM在-server模式下運行時,代碼將被優化:

假設tick()方法為:

public void tick(){
   System.out.println("tick");
}

優化后的最終代碼可能是:

public void run() {
  long lastTime = System.nanoTime();
  int ticks = 0;
  int frames = 1;
  double unprocessed = (System.nanoTime() - lastTime) / 16666666.66 -1 ;
  // tick method will inline here instead of invoking tick();
  System.out.println("tick");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM