バグの背景に、あるアプリケーショントレジャーのチャネルパッケージにJava層のOOMが出現していました。
Java ヒープ メモリ ルームには 2 つの状況があります。
- 1 つは、Java の新しいオブジェクトによって占有されるヒープ メモリが最大上限 maxMemory に達し、384m または 512M を超えることです。
- 2 つ目は、十分な連続アドレス空間がないことです。この状況は通常、プロセス内の多数のメモリ フラグメントによって引き起こされます。スタック情報には、最初の OOM スタックよりも多くの情報が含まれます: フラグメンテーションにより失敗しました (連続的な空きが必要です) << required_bytes << “bytes for a newbuffer where biggest contiguous free ” << biggest_continuous_free_pages << “bytes)”; 詳細なコードは art/runtime/gc/allocator/rosalloc.cc にあります。エラー ログから判断すると
、バグによりキャプチャされた Java ヒープ メモリの OOM は 2 番目のタイプに属し、十分なサイズの連続した領域がありません。
現象
Java 呼び出しスタックを確認します。Java
ヒープ メモリは 4.8M しかありませんが、17M のビットマップが生成されるため、OOM が直接スローされます。Android 8.0 より下では、ビットマップが占有するメモリは Java ヒープ内にあります。
8.0 より前のすべてのデバイスのデバイス情報を確認します。
分析プロセス
どのオブジェクトが Java ヒープ メモリを使い果たしているのか、またはメモリ リークが発生しているのかを確認するため。
次に、ゲームのアプリ トレジャー チャンネルのデバッグ パッケージをコンパイルし、現在のメモリ スナップショットを取得します。20
個を超える 17M ビットマップ (28*17m=476M) があり、現在のデバイスは Android 12 であることがわかります。そのため、ビットマップ メモリはネイティブ ヒープ内にあり、oom 現象は発生しませんでした。Android 8.0 より前のデバイスでこの問題が発生すると、Java ヒープ (ミニの世界では Java ヒープ 512M) が直接過負荷になり、oom が発生します。
その後、電話の結果、Tencent の特定の SDK にある AnimationDrawable によって引き起こされる問題であることが判明しました。
最終的に、問題はパートナー (アプリケーション テクノロジー) に報告され、Tencent Apex の SDK がホット アップデートされて問題が修正される予定です。
外部 SDK にアクセスするときは、制御不能なリスクを回避するために、デモ上のメモリ、スレッド、および fd の検出を試みてください。