2011-03-18 102 views
0

我的一個項目存在一些內存問題。一下就在我的程序的幾個位置追蹤內存之後,我追溯了問題這一行:如何正確解引用緩衝區?

(FloatBuffer)lightBuffer.asFloatBuffer().put(lightAmbient).flip() 

我使用得到緩衝的功能直線距離,但似乎是float緩衝區不會被清空在它被使用之後。 那麼如何在java中正確地清空/取消引用緩衝區?

ps:我嘗試了clear()方法,但根據只重置緩衝區的java文檔;它不會從中刪除數據。

+0

爲什麼不夠清楚?之後您可以重新使用緩衝區,就好像數據已發佈一樣。或者,您可以使緩衝區符合垃圾回收條件並創建一個新的垃圾回收站。 – Thomas 2011-03-18 20:42:57

回答

2

假設你lightBuffer是一個字節緩衝區(似乎沒有其它類有一個方法asFloatBuffer),你的FloatBuffer目的是僅圍繞相同的基礎byte[]或本機內存的包裝。

這個FloatBuffer對象不會再吃任何更多的內存(但使用與lightBuffer使用的內存相同的內存),但它可能會阻礙ByteBuffer的垃圾回收 - 但看起來你正在重用這個,不是嗎?

所以目前似乎沒有問題(除了你不知道有幾個緩衝區使用相同的內存)。

+1

+1只是一個註釋:有時(很少)有很多正在分配的直接緩衝區(可能是另一個問題)沒有足夠的GC壓力來使它們「死亡」得足夠快。有一些使用「內部」方法的黑客迫使直接緩衝區儘早釋放其支持。 – 2011-03-18 21:09:39

+0

lightBuffer是一個ByteBuffer,是的(抱歉..忘了包括它)。我也在重複使用lightBuffer。我也不知道他們使用相同的內存。那麼我想我的記憶問題是在別的地方。 – Bartvbl 2011-03-18 21:33:25

+0

事情是;一旦我註釋掉這一行,程序的內存使用量就是不變的。一旦啓用它,它就會開始以大約300 Kb/s的速度泄漏內存。所以我完全被這個事實困惑,尤其是因爲你說內存是共享的;它不應該這樣做。 – Bartvbl 2011-03-18 21:39:24

2

您是否在某處存儲了對此緩衝區的引用?我不認爲你可以明確地「從緩衝區中刪除數據」,並且System.gc()在這裏不會幫助你。

垃圾回收器應該自動爲您處理,除非您維護對此緩衝區的引用。

+0

+1只是一個註釋:有時(很少)有直接緩衝區,其中很多正在分配(可能是另一個問題),沒有足夠的GC壓力使它們「死亡」足夠快,因爲直接緩衝區的數據不受管理。有一些使用「內部」方法的黑客迫使直接緩衝區儘快釋放它的支持,但不幸的是,沒有可關閉/一次性接口。當然,使用這樣一個緩衝區和一個已發佈的後臺會導致令人討厭的異常:-) – 2011-03-18 21:11:19

+0

我正在創建緩衝區對象,然後將它傳遞給一個openGL函數。上面的代碼來自該函數的其中一個參數,所以我猜這不應該在後面留下任何參考,除非openGl保留它。哪個_不應該是這種情況 – Bartvbl 2011-03-18 21:48:32

0

呃,你沒有。

這些NIO緩衝區不會浪費時間,它們會覆蓋緩衝區中的數據並移動標記。

如果你想擺脫它,你必須擺脫它的所有引用,並提供給GC,以便它可以收集。