次のような配列宣言があります。
int a[];
これはプリミティブ型a
の配列です。int
この配列はどこに保存されますか? ヒープまたはスタックに保存されますか? これはint
プリミティブ型です。すべてのプリミティブ型がヒープに格納されるわけではありません。
次のような配列宣言があります。
int a[];
これはプリミティブ型a
の配列です。int
この配列はどこに保存されますか? ヒープまたはスタックに保存されますか? これはint
プリミティブ型です。すべてのプリミティブ型がヒープに格納されるわけではありません。
グルクルキが言ったように、それはヒープに保存されます。ただし、あなたの投稿は、おそらく「プリミティブは常にスタック上に存在する」という神話を広める善意のある人による誤解を示唆しています。これは真実ではありません。ローカル変数はスタック上に値を持っていますが、すべてのプリミティブ変数がローカルというわけではありません...
たとえば、次のように考えてください。
public class Foo
{
int value;
}
...
public void someOtherMethod()
{
Foo f = new Foo();
...
}
さて、どこにf.value
住んでいますか?神話はそれがスタック上にあることを示唆していますが、実際には新しいFoo
オブジェクトの一部であり、ヒープ1に存在します。f
(それ自体の値は参照であり、スタック上に存在することに注意してください。)
そこから、配列への簡単なステップです。配列は単に多くの変数であると考えることができます。これnew int[3]
は、次の形式のクラスを持つことに少し似ています。
public class ArrayInt3
{
public readonly int length = 3;
public int value0;
public int value1;
public int value2;
}
1実際には、これよりも複雑です。スタック/ヒープの区別は主に実装の詳細です。一部の JVM (おそらく実験的なもの) は、オブジェクトがメソッドから決して「エスケープ」しない時期を判断でき、オブジェクト全体をスタックに割り当てることができると思います。ただし、気にすることを選択した場合、概念的にはヒープ上にあります。
ヒープに格納されます
配列はJavaのオブジェクトだからです。
編集 :あなたが持っている場合
int [] testScores;
testScores = new int[4];
このコードは、コンパイラに対して、「4 つの int を保持する配列オブジェクトを作成し、それを という名前の参照変数に割り当てますtestScores
。また、各int
要素をゼロに設定してください。よろしくお願いします」と考えてください。
それ自体はプリミティブではないプリミティブ型の配列です。経験則として、 new キーワードが含まれる場合、結果はヒープ上にあるということです。
このテーマで実行したいくつかのテストを共有したかっただけです。
サイズ 1000 万の配列
public static void main(String[] args) {
memInfo();
double a[] = new double[10000000];
memInfo();
}
出力:
------------------------
max mem = 130.0 MB
total mem = 85.0 MB
free mem = 83.6 MB
used mem = 1.4 MB
------------------------
------------------------
max mem = 130.0 MB
total mem = 130.0 MB
free mem = 48.9 MB
used mem = 81.1 MB
------------------------
ご覧のとおり、使用済みヒープ サイズは最大 80 MB (10m * sizeof(double)) 増加します。
しかし、double の代わりに Double を使用している場合
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
memInfo();
}
出力は 40MB と表示されます。Double 参照のみがあり、初期化されていません。
Double で埋める
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
Double qq = 3.1d;
for (int i = 0; i < a.length; i++) {
a[i] = qq;
}
memInfo();
}
それでも40MB。それらはすべて同じ Double オブジェクトを指しているためです。
代わりに double で初期化する
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
Double qq = 3.1d;
for (int i = 0; i < a.length; i++) {
a[i] = qq.doubleValue();
}
memInfo();
}
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
ライン
a[i] = qq.doubleValue();
と同等です
a[i] = Double.valueOf(qq.doubleValue());
これはと同等です
a[i] = new Double(qq.doubleValue());
毎回新しい Double オブジェクトを作成するため、ヒープを吹き飛ばします。これは、Double クラス内の値がヒープに格納されていることを示しています。
Java プログラミング言語では、配列はオブジェクトであり、動的に作成され、Object 型の変数に割り当てることができます。
http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html