4

現在、C# (Windows Phone 用) で開発したゲームを Java (Android) に移植中です。

Java バージョンでメモリの問題が発生しています。これは、プロファイリング後、メモリ内の膨大な数のStringオブジェクトから発生しているように見えます。これは、明らかに の不変の性質によるものStringです。これで、プレーヤーのスコアを画面にレンダリングするメソッドまでた​​どることができました。ここでInteger.toString()は、スコアが変化するたびに a が使用されます (1 秒間に何度も)。使用しているフレームワークのテキスト レンダリング メソッドは のみを引数として受け入れるため、実際には a を使用できませんStringBuilder(これは C# バージョンにあるものです) String。したがって、とにかく変換​​が行われます。

これはJavaでよくある問題ですか?誰かが解決策を推奨できますか (フレームワーク開発者に連絡してメソッドを変更するよう依頼する以外に!)?

アップデート:

ゲームは非常にペースが速く、スコアは現在の「ステージ」の開始からの経過時間に部分的に基づいています。1 秒間に 15 回更新されます。

文字列への参照は保持していませんが、フレームワークがこれらの文字列をリークまたは複製しているのではないかと考えているので、それを調べようとしています (これは公開フレームワークではなく、私の知る限り、使用されていませんこの種のテンポの速いゲームではまだ)。

プーリングは良い提案であり、私はそれを試してみることを考えましたが、一定の値を設定するにはスコアリング システムを変更する必要があります。

4

2 に答える 2

2

特定のケースで役立つかどうかはわかりませんが、一般に、操作している文字列値の固定セットがある場合、それらすべてを文字列プールに追加することは理にかなっています。この場合、JVM に新しい文字列ごとにヒープ上にオブジェクトを作成させずに、文字列プールを利用させることができます。

たとえば、次のように、プールから文字列を返すようにコードを変更する必要があります。

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

javadoc からの追加説明:

intern メソッドが呼び出されたときに、equals(Object) メソッドによって決定されたこの String オブジェクトと等しい文字列がプールにすでに含まれている場合、プールからの文字列が返されます。それ以外の場合は、この String オブジェクトがプールに追加され、この String オブジェクトへの参照が返されます。

于 2013-03-02T17:11:23.833 に答える
0

最終的には、固定長の char 配列に裏打ちされた独自の変更可能な文字列クラスを作成し、初期化後にゼロ割り当てで独自のテキスト レンダリング メソッドを作成することで、問題を解決しました。

この後、すべてがはるかにスムーズに実行されましたが、GC によって引き起こされた「フリーズ」がまだいくつかありました。プロファイリングの結果、これはメイン ゲーム ループ中にループ内で大量のイテレータが作成されたことが原因であることが判明しました。次に、イテレータのプールを使用するカスタム配列クラスを作成したところ、すべてがうまく動作するようになりました!

于 2013-03-05T13:56:36.200 に答える