2011-10-24 17 views
1
private void func() 
{ 
    String str = "hi!"; 
} 

這是我的代碼。java中的變量生存期

假設我在onCreate事件中調用了func()。 我想要近準確的時間,如果可以確定,GC將釋放str使用的內存。

其實str存儲密碼。 我想盡快將它釋放。 目前在使用str之後,我將它的值設置爲無關緊要的東西。

我聽說GC是唯一可以釋放記憶的東西嗎? 是否正確? 是否有任何其他方式來釋放變量的內存。

+1

你完成後可以嘗試做'str = null;' – Ankur

+0

這是正確的,但你永遠不會知道什麼時候,它取決於VM的實現 –

+0

@max_force:這有什麼關係嗎?你期望什麼能夠訪問'str',瞭解它的目的是什麼,並且惡意使用它? – Squonk

回答

9

我想要近精確的時間,如果可以確定的話, GC將釋放str使用的內存。

壞運氣,你不能擁有它。

解決方案:將其存儲在char []而不是String中,並在完成後將char []的所有元素清零。

+4

這是一個很好的解決方案 - 請注意,即使在JDK本身,類似於java.io.Console.readPassword()的方法也會因爲完全相同的原因返回char []而不是String。 – Jesper

+0

@Jesper很好的觀察Jesper –

2

垃圾收集器一旦滿足不再引用它的條件,就有資格進行垃圾收集。

但是,因爲這是一個字符串,我記得這個文字仍然在字符串池中,但是它的對象引用將被GC銷燬。

但是,您不能影響GC的行爲。

對於這種方法,每次方法退出時,變量都會超出範圍,當它超出範圍時,變爲符合GC要求,但GC是否決定釋放它,我們無法控制或預測。

+1

好吧,*文字*將在字符串池中。希望真正的密碼不會像這樣硬編碼:) –

+0

我明白了Jon! –

1

在你的情況下,str不是問題,當你聲明一個字符串時,它被分配到你的應用程序的字符串池中。您應該創建一個chars數組。

關於GC,您在收集該內存時沒有任何保證。

1

我不太瞭解Dalvik VM,但在標準的Java中,沒有辦法從你的例子中釋放內存,因爲字符串「hi!」生活在不變的池塘裏。

如果更改爲

String str = new String("hi!"); 

,讓堆上的字符串,可以是GC。

2

首先,只要java需要這個字符串。理論上直到JVM終止。所以呢?誰可以連接到它並帶來價值?如何?

但是,如果您非常害怕,您可以撥打System.gc()那將可能觸發GC運行並刪除值。仍然沒有保證。

還有一個竅門。字符串包含其內容是私人字段char[] value。你可以用反射覆蓋它,所以沒人會知道你的密碼。

+0

'可能'太強了。 Javadoc只是說這是一個建議。 – EJP

1

你可以打電話System.gc(),但這只是建議,如果你看看java文檔。你不能在java中強制垃圾收集,一般來說這不是一個好主意。

如果你確實需要一個解決方案,你需要使用字節數組或者JNI編寫你自己的自定義密碼讀寫器,當然要非常小心,密碼永遠不會變成一個對象。否則你失敗了。