2012-03-12 18 views
2

我有一個應用程序,我在生成許多位圖對象。一旦我創建了一個位圖,所有剩下的位圖將會是相同的大小。最快的方法來加載位圖,重新使用位圖一旦創建

目前我可以在我的手機上大約50-80毫秒內加載/創建一個新的位圖,該工具適用於我所需要的。然而,由於創建這些的速度很快,我打了不斷的GC。

我想重新使用相同的位圖對象,但不知道如何通過sdk執行此操作。

我編譯libjpeg並通過NDK加載我的圖像並重新使用我的位圖,但是我的加載速度下降到大約200毫秒,這太慢了。 我將在稍後發佈代碼,當我把它放在我面前時。

問題:

有沒有辦法重新使用我的位圖對象,以避免GC? 有更快的方式通過NDK加載我的圖像嗎?是否有可能掛鉤操作系統加載位圖的方式?我知道libjpegTurbo,但目前我無法編譯它(另一天的另一個主題)。

任何其他想法的最佳方式來做到這一點。

回答

1

爲什麼不使用散列表來存儲您的位圖?然後當你加載一個位圖時,首先檢查它是否在hashmap中,如果是,你可以重用它。如果它不在hashmap中,請正常保存,然後將其插入到散列映射中。

+0

我每秒創建約20個位圖,所以我無法將它們全部留在內存中。我實際上有一個後臺線程填充一個隊列,我從中拉取新的位圖。最大的問題是在我的後臺線程中,而不是創建新的位圖對象,我想從一個位圖池中取出並重新使用它們,因此我不必擁有太多的GC。 – broschb 2012-03-12 15:19:33

+0

@broschb如果你不能將它們留在記憶中,那麼你如何重新使用它們?你意識到這沒有道理嗎?如果你有內存限制,那麼最好的辦法就是使用散列表和隊列來實現一個圖像緩存,然後一旦你加載的位圖數量達到一定限制,從隊列中刪除舊的位圖並提示GC他們應該被清理出內存。散列表將用於識別位圖當前是否在隊列中及其位置。 – onit 2012-03-12 15:23:33

+0

我可以通過更改位圖的像素數據以及來自其他位圖的新像素數據來重新使用位圖。看@Samuels的迴應,我認爲這是我正在思考的軌道。 – broschb 2012-03-12 17:33:15

1

我會推薦使用含有您需要換出的像素數據的IntBuffer(s)。然後,創建一個您需要的大小的位圖,並且當您需要交換像素時,請使用bitmap.copyPixelsFromBuffer()。我想這比每次需要更改像素數據時分配/取消分配位圖內存要快得多。如果您想將緩衝區保存在內存中以便快速檢索,那麼將緩衝區保存在散列表中可能是一個好主意。

(可選)您可以將setPixels()與int數組一起使用。 copyPixelsFromBuffer()的好處是沒有嘗試像素轉換,並且選項較少,所以它可能會更快一些。

+0

我喜歡int緩衝區的想法,但是我看到的唯一重大收益可能是內存空間。最快的方法是將對象保存在內存中,在這種情況下,如果int緩衝區顯着小於位圖對象,這隻會是一個重大改進。我對此抱有懷疑,除非位圖相對較小。 – onit 2012-03-12 15:34:58

+0

像素數據來自哪裏?它在某個時刻必須是一個int數組,對嗎?所以如果你每次都分配一個位圖,那麼你的int數組和內存的位圖就有內存。假設你已經完成了int數組,這是一個需要垃圾回收的對象。然後當你完成位圖時,它也需要被垃圾收集。這是需要垃圾收集的兩大對象。如果只使用一個位圖,則不會有需要垃圾收集的額外對象。位圖GC需要更長的時間,因爲它也有JNI調用。 – Samuel 2012-03-12 15:53:48

+0

如果您正在重新使用內存中的位圖,GC不再成爲一個大問題,除非您擁有大量無法在內存中緩存的圖像(我已經親自在新手機上將數百個位圖存儲在內存中)。我想,至少有95%的位圖使用的內存也是實際的底層int數組,除非你有非常小的位圖。如果他只能緩存內存中的位圖(這將是最大的性能提升),我懷疑這會是一個顯着的性能提升。如果他需要不斷回收Bitmap,我同意這會有所改進。 – onit 2012-03-12 15:59:15