2014-09-29 137 views
1

我製作了一個包含JButton的JFrame(稱爲J1)。點擊該按鈕後,將打開一個新的JFrame(稱爲J2)。 J1也有一個ArrayList,其中包含J2以及所有已打開的其他Jframe。 J2設置爲DISPOSE_ON_CLOSED 我設置爲J2 a windowClosed()方法。爲了進行測試,在JFrame裏面我打了一圈ArrayList,直到我剛剛關閉的當前J2,並且出乎意料地當我做J2.setVisisble(true)時,J2窗口返回!如何完全關閉/刪除JFrame

我也查扔了任務管理器,看到雖然打開一個新的J2,將會使整個程序消耗更多的內存,關閉每個J2不顯示在任務管理器太大的區別,它看起來並不像任何內存都被釋放。看起來內存消耗在幾秒鐘後回到「正常」,所以我懷疑這與J2有什麼直接關係。

我試圖打印(System.out.print)所有ArrayList每一個新J2開始時間的內容,並打開窗戶,關閉它,並打開一個新的後,我得到以下messgae:

home.ATMmachine[frame0,252,198,620x420,invalid,hidden,layout=java.awt.BorderLayout,title=ATM Machine No.1,resizable,normal,defaultCloseOperation=DISPOSE_ON_CLOSE,rootPane=javax.swing.JRootPane[,9,38,602x373,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true] 

這意味着J2並未完全刪除!

JFrame中dispose()方法是假設

釋放由此Window,其子組件所使用的本機屏幕資源,其擁有的所有兒童。也就是說,這些組件的資源將被銷燬,它們消耗的所有內存將被返回到操作系統,並且它們將被標記爲不可顯示。

所以,我只是錯了,框架被刪除累計時間後。

如果沒有,那麼我怎樣才能刪除框架以引用它的方式就像引用null?

+2

'「關閉每個J2不顯示在任務管理器太大的差別,......」「 - 可能是因爲GC'ing需要的時候纔會出現,所以雖然您的對象被標記爲GC'ing,但可能因爲沒有必要已經被收集。在一個側面說明 - 爲什麼所有的JFrames?我用過的大多數程序都會給你帶來很多窗口,看起來很煩人,我想這就是爲什麼我通常只看到新手程序員以這種方式創建它們的原因。爲什麼不用CardLayout交換視圖? – 2014-09-29 21:19:29

+1

'「J2.setVisisble(true)」' - 這裏不足爲奇。調用'dispose()'釋放資源。調用'setVisible(true)'重新創建並重新使用資源。你仍然有一個對象的引用,那麼如果你可以再次設置它,所以不會發生GC'ing。 – 2014-09-29 21:22:17

+0

''這意味着J2沒有被完全刪除!「 - 你不想把對象與資源混淆,這正是你在這裏做的。您保留了對該對象的引用(否則println無法完成),因此它當然存在並且一直存在,直到引用不再存在(您不能打印任何內容),並且由於它繼續當然存在打印出來會返回你所看到的。 – 2014-09-29 21:27:00

回答

0

框架j2仍然在ArrayList中被一個指針引用,所以垃圾收集器不能處理它呢...嘗試從arraylist中刪除指針,然後即使j2仍然存在於RAM中,它在你的程序中不會有任何引用,所以垃圾收集器應該在下一次傳遞時刪除它,或者如果你調用system.gc()。

+0

['System.gc()'](http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#gc%28%29)只是一個建議。它不能保證會發生任何事情, – 2014-09-29 22:00:04

+0

是啊謝謝你指出,只是試圖以最簡單的方式傳遞信息給問的人;) – vlatkozelka 2014-09-29 22:06:06

5

我製作了一個包含JButton的JFrame(稱爲J1)。點擊該按鈕後,將打開一個新的JFrame(稱爲J2)。 J1還包含一個ArrayList,其中包含J2以及所有已打開的其他Jframe。 J2設置爲DISPOSE_ON_CLOSED我爲J2設置了一個windowClosed()方法。爲了進行測試,在JFrame中,我打開了ArrayList,直到我剛剛關閉了當前的J2,並且出乎意料地當我執行J2.setVisisble(true)時,J2窗口返回!

關閉JFrame並處理不會破壞JFrame對象,而是釋放系統資源,即在您的操作系統上顯示窗口所需的資源。這與對象本身完全不同。當您在廢棄的JFrame上調用setVisible(true)時,將重新創建資源,並重新顯示該窗口。沒有對象被創建或銷燬。

我也查了扔了任務管理器,看到雖然打開了一個新的J2,會讓整個程序消耗更多的RAM,關閉每個J2並沒有在任務管理器上顯示太大的差別,它沒有看起來像任何內存被釋放。看起來內存消耗會在幾秒鐘後回到「正常」,所以我懷疑這是否與J2有直接關係。

那裏不足爲奇。

我試圖打印每一個新的J2開始時間(是System.out.print)所有ArrayList的內容,並打開窗戶,關閉它,並打開一個新的後,我得到以下messgae:

home.ATMmachine [frame0,252,198,620x420,invalid,hidden,layout = java.awt.BorderLayout,title = ATM Machine No.1,resizable,normal,defaultCloseOperation = DISPOSE_ON_CLOSE,rootPane = javax.swing.JRootPane [,9 ,38,602x373,invalid,layout = javax.swing.JRootPane $ RootLayout,alignmentX = 0.0,alignmentY = 0.0,border =,flags = 16777673,maximumSize =,minimumSize =,preferredSize =],rootPaneCheckingEnabled = true]

This意思那J2完全沒有被刪除!

再次,你混淆了對象,只要對對象的引用存在,資源就會存在。

的JFrame的Dispose()方法是假設 釋放由此Window,其子組件所使用的本機屏幕資源,其擁有的所有兒童。也就是說,這些組件的資源將被銷燬,它們消耗的所有內存將被返回到操作系統,並且它們將被標記爲不可顯示。

沒錯。

所以我只是錯了,框架被刪除累計時間後。

只有在沒有更強的引用時才能GC'd對象,並且垃圾回收器只在感覺需要時纔會執行此操作,例如內存即將用完時。

如果不是,那麼我如何刪除框架以引用它的方式將引用爲空?

就像任何其他物體。你可以在本地創建一個,但要小心,因爲Swing監聽器有辦法創建強引用,你會認爲它應該是弱的,從而使對象持久的時間比你想要的長。


在旁註 - 爲什麼所有的JFrames?我用過的大多數程序都會給你帶來很多窗口,看起來很煩人,我想這就是爲什麼我通常只看到新手程序員以這種方式創建它們的原因。爲什麼不用CardLayout交換視圖?

請查看:更多The Use of Multiple JFrames, Good/Bad Practice?這個

+0

我只是在學習鞦韆,所以我試圖全部種類的東西。但是,除了在本地創建對象之外,沒有辦法完全摧毀對象嗎?我想要一個將對象的引用更改爲null的方法,因此無法再引用它。 – 789 2014-10-01 10:01:26