メモリから計算アルゴリズムを最適化する際、特定の(非常に合理的な)入力パラメーターを使用すると、float [500] [14761] [2]の配列が作成されるという事実に出会いました。 (HotSpot 1.6.0_26 32ビットで、誰かが興味を持っている場合)メモリをどれくらい取ることができますか? 概算で、
私はインターネットでこの主題について書かれていることを検索し、英語で「 Java配列のメモリ使用量を計算する方法 」というかなり理解しやすい記事に出会いました。 簡単に言うと、プレゼンテーションの本質は次のとおりです。
- すべてのJavaオブジェクトには8バイトのオーバーヘッドがあります。
- Java配列には、追加の4バイトのオーバーヘッド(サイズの格納用)があります。
- リンクのサイズは4バイトです。
- すべてのオブジェクトのサイズは8バイトで調整されます。
- 多次元配列は、配列参照の配列です。
この知識で十分です。 したがって、チェーンの最後にfloat [2]配列があります。 サイズは2フロート(各4バイト)+ 12バイトのオーバーヘッド-20バイトです。 8〜24バイトに揃えられます。 合計で、
次に、float配列が
最後に、作成した実際の配列があります-float [500] [] []-2次元配列への500参照の配列。
何が起こったのかを合計します:
すぐに明らかな決定が浮かびました。配列の次元を昇順で並べることです。 float [2] [500] [14761]を作成しますが、アルゴリズムはこの問題を一切受けません。 この場合、どのサイズになりますか?
- 配列フロート[14761]:
14 761 * 4 + 12 =59 056 バイト、合計1,000の そのような配列、合計59 056 000 バイト。 - 配列float [500] []:
500 * 4 + 12 =2 012 、アライメント後-2 016 、合計2つのそのような配列で、合計4 032 バイト。 - 配列float [2] [] []:アライメント後の
2 * 4 + 12 = 20-24バイト。
合計で59,060,056バイト、0.03%未満のオーバーヘッド、約150メガバイトのメモリが節約されました。
ここからは経験則に従います。測定による配列の次元が少なくとも事前にわかっている場合は、測定値を昇順に並べる必要があります。 また、メモリアナライザーを使用することも忘れないでください。プログラムについて多くを学ぶことができます。