首頁>Program>source

我是一名进入Java世界的C ++程式員.而且,我不能删除必须让Java垃圾收集器进行清理的不良感覺。

例如,此代碼將如何在Java中執行?

public void myFunction() {
    myObject object = new myObject();
    object.doSomething();
}

当myFunction()退出時,是否將删除區域性變數物件?

我是否必须在退出之前將物件設置為null,否則它將超出範圍並被GC删除吗? 或者,在最壞的情况下,它会像在C ++中那樣洩漏吗?

最新回復
  • 5月前
    1 #

    在不再使用後的某个時候,它將在處被垃圾迴收.我相信在Java的当前實現中,它實際上將一直保留到方法結束時,而.NET中的垃圾收集器則更具攻击性. (即使在Java中,我也不知道是否有任何保證。通常,您只想想要在除錯時將本地變數保留到其上次可能讀取的範圍之外。)

    但是不,您不需要將變數設置為null,否則会损害可讀性。

    方法退出後,物件不太可能立即立即进行垃圾迴收; 這取決於GC的執行時間……而且,当然,如果有任何其他保留该物件的引用,則该物件可能仍不適合进行垃圾收集.不要忘記變數的值只是一个引用,而不是物件本身. (這可能需要一段時間才能习惯於C ++。)

  • 5月前
    2 #

    GC至少在記憶體限製接近時才開始工作,因為超出範圍的變數引用的任何物件都可以被垃圾迴收, 但是最後一个退出的塊存在超出範圍的區域性變數的意外行為。

    让我们来比较一下:

    {
       final List myTooBigList = new ArrayList();
       ... overfill the list
    }
    somethingRunOutOfMemory();
    

    somethingRunOutOfMemory() 因為 myTooBigList 不能使用GC,尽管範圍不再可用,並且要求更多的記憶體,与以下不同:

    {
       final List myTooBigList = new ArrayList();
       ... overfill the list
    }
    Object fake = null;
    somethingDoesNotRunOutOfMemory();
    

    fake的影响 向後移動堆棧指標,让 myTooBigList GCable,然後只要記憶體限製接近,GC就会開始工作。 令人惊讶的是(至少在我正在測試的jvm中),我们必须在同一級別上顯式地重用堆棧.可以預料到,一旦退出该塊,區域性變數就可以被GC使用,但是我认為這是對效能的一種折衷.這樣会使位元組複雜得多。

    像C中一樣,區域性變數位於框架旁邊的堆棧中。 堆棧指標為範圍內的區域性變數保留所需的空間。 重用堆棧時,{退出塊}的區域性變數變為GCable,即:在同一堆棧級別上宣告區域性變數之後,函式返迴之後或退出評估(捕获,迴圈條件)之後。

    在:之後它们是可GC使用的

    try { } catch : after exit by catch because catch reuses stack
    for { } : after exit loop condition  because evaluation reuses stack
    while { } : after exit loop condition because evaluation reuses stack
    { } declare=value : after any declaration+affectation that reuses stack
    

    在:之後它们不能被GC使用

    try { } : after nothing caught
    for { } : after exit by break
    while { } : after exit by break
    do { }
    if { }
    { }
    

    註意:要进行實驗,請執行GC,然後比较 WeakReference(my variable)null

    final WeakReference gctest;
    {
       final List myTooBigList = new ArrayList();
       gctest = new WeakReference(myTooBigList);
       ... overfill the list
    }
    Object fake = null;
    System.gc();
    assert gctest.get() == null;
    

  • 5月前
    3 #

    它將超出範圍.在Java中,当没有人再指向一个物件時,该物件將被垃圾迴收,或者至少可用於垃圾迴收.無需在此處將其設置為null.有時,如果您的物件將存在於您的App中,則需要將物件引用設置為null,但是需要對其进行儲存的引用进行垃圾收集.在這種情况下,您選擇釋放參考。

相似問題

  • c#:PictureBox問题
  • c#:查詢代碼速度極慢,但SSMS快速