多くのオブジェクトを格納するために効率的なメモリが必要な場合があります。Java でこれを行うには、いくつかのプリミティブ配列 (以下の理由を参照) を使用するか、変換のために少し CPU オーバーヘッドを生成する大きなバイト配列を使用する必要があります。
例: を持っていclass Point { float x; float y;}
ます。ここで、32 ビット JVM で、少なくとも浮動小数に N * 8 バイト、参照に N * 4 バイトかかる N ポイントを配列に格納する必要があります。したがって、少なくとも 1/3 はガベージです (ここでは、通常のオブジェクト オーバーヘッドはカウントされません)。しかし、これを 2 つの float 配列に格納すれば、すべて問題ありません。
私の質問: Java が参照配列のメモリ使用量を最適化しないのはなぜですか? C++ で行われているように、オブジェクトを配列に直接埋め込まないのはなぜですか?
たとえば、クラス Point final のマーク付けは、JVM が Point クラスのデータの最大長を確認するのに十分なはずです。または、これはどこで仕様に反するのでしょうか? また、これにより、大きなn次元行列などを処理するときに多くのメモリが節約されます
更新:
JVM が理論的に (舞台裏などで) 最適化できるかどうか、またどのような条件下で JVM を強制できるかどうかではなく、知りたいです。結論の 2 点目は、簡単にできない理由だと思います。
JVM が知る必要がある結論:
- JVM が 1 つの配列エントリの長さを推測できるようにするには、クラスを final にする必要があります。
- 配列は読み取り専用である必要があります。もちろん、 のように値を変更することはでき
Point p = arr[i]; p.setX(i)
ますが、 を介して配列に書き込むことはできませんinlineArr[i] = new Point()
。または、JVM は「Java 方式」に反するコピー セマンティクスを導入する必要があります。アロスの答えを見る - 配列を初期化する方法 (既定のコンストラクターを呼び出すか、メンバーを既定値に初期化したままにする)