原语的Java数组存储在堆栈还是堆中?
我有这样一个数组声明:原语的Java数组存储在堆栈还是堆中?,java,arrays,stack,heap,primitive-types,Java,Arrays,Stack,Heap,Primitive Types,我有这样一个数组声明: int a[]; 这里是一个基本int类型的数组。这个数组存储在哪里?它是存储在堆上还是堆栈上?这是一个primitve类型int,所有的基元类型都不存储在堆上。它将存储在堆上 因为数组在java中是一个对象 编辑:如果你有 int [] testScores; testScores = new int[4]; 将这段代码想象为对编译器说,创建一个包含四个整数的数组对象,并将其分配给名为testScores的引用变量。另外,继续并将每个int元素设置为零。谢谢。在J
int a[];
这里是一个基本int类型的数组。这个数组存储在哪里?它是存储在堆上还是堆栈上?这是一个primitve类型int,所有的基元类型都不存储在堆上。它将存储在堆上
因为数组在java中是一个对象
编辑:如果你有
int [] testScores;
testScores = new int[4];
将这段代码想象为对编译器说,创建一个包含四个整数的数组对象,并将其分配给名为testScores的引用变量。另外,继续并将每个int元素设置为零。谢谢。在Java编程语言中,数组是对象,是动态创建的,可以分配给Object类型的变量
它是一个基元类型数组,其本身不是基元类型。一个好的经验法则是,当涉及新关键字时,结果将在堆上。正如gurukulki所说,它存储在堆上。然而,你的帖子暗示了一个误解,可能是因为一些好心人宣扬原始人总是生活在堆栈上的神话。这是不真实的。局部变量的值在堆栈上,但不是所有的基元变量都是局部变量 例如,考虑这一点:
public class Foo
{
int value;
}
...
public void someOtherMethod()
{
Foo f = new Foo();
...
}
现在,f.value住在哪里?神话可能暗示它在堆栈上,但实际上它是新Foo对象的一部分,并且生活在heap1上。请注意,f本身的值是一个引用,并且存在于堆栈中
从这里开始,很容易找到阵列。你可以把数组看作是很多变量——所以新的int[3]有点像有这样一个类:
public class ArrayInt3
{
public readonly int length = 3;
public int value0;
public int value1;
public int value2;
}
事实上,它比这更复杂。堆栈/堆的区别主要是一个实现细节——我相信一些JVM(可能是实验JVM)可以判断对象何时从不从方法中逃逸,并且可以在堆栈上分配整个对象。但是,如果你愿意的话,它在概念上是堆上的。我只想分享我在这个主题上运行的几个测试 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
------------------------
如您所见,使用的堆大小增加了约80MB,即10m*sizeofdouble
但是如果我们用Double代替Double
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
memInfo();
}
输出将显示40MB。我们只有双重引用,它们没有初始化
用双份的
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();
}
相当于
a[i] = Double.valueOf(qq.doubleValue());
a[i] = new Double(qq.doubleValue());
这相当于
a[i] = Double.valueOf(qq.doubleValue());
a[i] = new Double(qq.doubleValue());
因为我们每次都会创建新的双对象,所以我们会吹出堆。
这表明Double类中的值存储在heap中。这不是数组。它是对数组的引用。如果引用本身是类或对象的成员,则可以将其存储在堆上;如果引用本身是方法中的局部变量,则可以将其存储在堆栈上。如果基元类型是类或对象的成员,则它们可以存储在堆上。堆上数组的名为testScorespointing的引用变量将位于堆栈上。只有在向编译器提供-g选项时,代码才会显示感谢。否则它将被优化掉。@mob您假设这是唯一的代码。假设这两行代码是实际使用数组的大型程序的一部分可能更好。关于Java中的转义分析:它说,它自JDK 6 Update 14的早期access发行版起就存在,并在JDK 6 Update 23的默认情况下启用。如果数组是公共静态final,它会改变什么吗?那么它不应该是固定池的一部分吗?@Malachiasz:不。数组从来都不是常量。@JonSkeet:据我所知,在Java库的所有版本中,每个字符串都有一个char[]作为后盾。我相信文字字符串存储在公共常量池中;对于GC优化,这意味着应该同样存储备份阵列,否则必须在任何GC循环期间扫描常量池,否则备份阵列将有资格收集。@supercat:是的,这是有意义的。但是你声明的任何数组都不会成为常量池的一部分。你能粘贴memInfo的代码细节吗