Java数组使用堆栈空间

12

这是声明Java数组的常规方式:

int[] arr = new int[100];

但是这个数组使用了堆空间。是否有一种方法可以像 C++ 一样使用栈空间声明一个数组?


1
@JigarJoshi:更多的stackoverflow。 - tskuzzy
数组是一个容器对象。所有的对象都存储在堆上。 - jn1kk
1
@JigarJoshi 我认为在堆栈中访问空间会更快。 - icn
6
如果你在堆上创建或收集数据,可能会损失一两个微秒的时间,但是,除非你需要执行这种操作数百万次,否则担心这种优化没有多大意义。 - user949300
4个回答

21

不管它是包含原始类型还是对象类型,数组都是对象,因此像其他任何对象一样,它在堆上分配了空间。

但是从Java 6u23版本开始逃逸分析应运而生,并且在Java 7中默认激活

逃逸分析关注对象的作用域当一个对象在方法作用域内定义而不是类作用域内时,JVM就知道该对象无法逃脱此有限方法作用域,并对其应用各种优化,例如常量折叠等。

Then it can also allocate the object which is defined in the method scope,
on the Thread's Stack, which is accessing the method.

12

简而言之,不行。

在堆栈上存储的只有基本类型和对象引用。在您的示例中,arr引用存储在堆栈上,但它引用的数据存储在堆上。

如果您因为想确保内存已清理而从C++转到Java并提出这个问题,请阅读有关垃圾收集的文章。简单来说,Java会自动处理清理堆内存以及堆栈上的内存。


如果JIT看到通过将数组保留在内存中的特定位置来进行优化的机会,它可能会这样做,但那是它的工作,而不是你的。 - Louis Wasserman

3

数组是动态分配的,因此它们位于堆上。

我的意思是,当您执行以下操作时会发生什么:

int[] arr = new int[4];
arr = new int[5];

如果第一次分配是在堆栈上完成的,我们如何进行垃圾回收呢?引用arr存储在堆栈上,但实际的数据数组必须存储在堆上。

1

这还不是一种语言特性,因为这需要值类型,因为通过引用传递栈上数据将不安全。

但作为优化(逃逸分析),如果JVM可以证明它不会离开局部/被调用者范围,则可能已经对包含小型固定大小数组的局部变量进行了优化。话虽如此,这只是一种运行时优化,而不是某些规范保证,因此依赖它是困难的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接