2013-03-02 40 views
4

我目前在移植的C#(用於Windows手機)開發的遊戲的Java(Android版)的過程。內存問題頻繁Integer.toString()轉換

我們遇到的Java版本內存問題其中,分析後,似乎是從String對象數量巨大未來在內存中,顯然由於String的不可變的性質。現在,我已經設法追蹤到將玩家的得分呈現在屏幕上的方法,每次得分改變時(每秒多次)使用Integer.toString()。我真的不能使用StringBuilder,因爲我們只使用了框架的文本渲染的方法(這是我們在C#版本)接受String的作爲參數,因此轉換反正發生。

這是Java中的常見問題嗎?任何人都可以推薦一個解決方案(除了聯繫框架開發人員,讓他們修改他們的方法!)?

更新:

這場比賽是非常快的節奏,比分也是部分基於因爲目前的「階段」的開始經過的時間。它每秒更新15次。

我們不保留對字符串的引用,但我在想,也許框架泄漏或複製這些字符串,所以我試圖調查一下(它不是一個公共框架,並且據我所知它沒有還沒有用於這種快節奏的比賽)。

該池是一個很好的建議,我想嘗試這一點,但在評分系統將不得不爲了有一個固定的值進行修改。

+0

你多久更新屏幕上的分數? – 2013-03-02 17:10:20

+0

你確定Integer.toString()是否是問題?通常沒有性能影響,除非你像100次/秒這樣做。 – 2013-03-02 17:13:16

+0

這個遊戲一次顯示多少個分數。如果內存中有大量的String對象,並且只需要一到兩個,這意味着該應用程序正在泄漏字符串,垃圾收集器無法收集它們。檢查探查器哪些對象引用了字符串,它可能會給你一個線索。 – 2013-03-02 17:18:47

回答

0

我們最終通過創建我們自己的可修改的字符串類來解決這個問題,該類由固定長度的char數組支持,並且在初始化後編寫我們自己的帶有零分配的文本呈現方法。

在此之後,一切都運行更加流暢,但我們仍然有引起GC幾個「凍結」。分析之後,事實證明這是由於主遊戲循環期間在循環中創建大量迭代器造成的。然後,我們編寫了一個使用迭代器池的自定義數組類,現在一切運行良好!

2

我不知道這是否有助於你的具體情況,但總的來說,當你有一些固定設置你與操作字符串值的,是有意義的他們都添加到字符串池。在這種情況下,您可以強制JVM不爲每個新字符串在堆上創建對象,而是使用字符串池。

你必須改變你的代碼從池中返回字符串,像這樣的例子:

return String.valueOf(123).intern(); 

從javadoc的一些補充說明:

當調用實習生方法,如果該池已經包含一個與equals(Object)方法確定的String對象相等的字符串,則返回該字符串。否則,將此String對象添加到池中,並返回對此String對象的引用。

+0

這是一個很好的建議,但如果每次分數更改爲新值,這種情況可能不適用。 – iTech 2013-03-02 17:12:45

+0

@iTech您是對的。從這個問題來看,這個分數是否是固定的,坦率地說,如果沒有一些分析信息,就很難說出問題是什麼。 – 2013-03-02 17:17:01