使用堆栈空间的 Java 数组

Posted

技术标签:

【中文标题】使用堆栈空间的 Java 数组【英文标题】:Java array using stack space 【发布时间】:2012-06-12 19:20:18 【问题描述】:

这是声明 Java 数组的常用方法:

int[] arr = new int[100];

但是这个数组正在使用堆空间。有没有办法像 c++ 一样使用堆栈空间声明数组?

【问题讨论】:

@JigarJoshi: moar ***. 数组是一个容器对象。所有对象都在堆上。 @JigarJoshi 我认为访问堆栈空间更快 Java Array is stored in stack or heap? 的可能重复项 在创建/从堆中收集时会损失一两微秒,但是,除非您经常这样做,否则担心这种优化是徒劳的。 【参考方案1】:

Arrays are objects 不管它是原始类型还是对象类型,所以和其他任何对象一样,它的allocated space on the heap.

But then from Java 6u23版本,Escape Analysis应运而生,由default activated in Java 7.

Escape Analysis is about the scope of the object,when an object is defined inside a method scope rather than a class scope,那么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.

【讨论】:

【参考方案2】:

一句话,没有。

存储在堆栈中的唯一变量是基元和对象引用。在您的示例中,arr 引用存储在堆栈中,但它引用了堆上的数据。

如果您问这个来自 C++ 的问题是因为您想确保清理内存,请阅读 garbage collection。简而言之,Java 会自动清理堆中的内存以及栈中的内存。

【讨论】:

如果 JIT 看到了通过将数组保存在内存中的特定位置来优化的机会,它可能会这样做,但这是它的工作,而不是你的工作。【参考方案3】:

数组是动态分配的,所以它们在堆上。

我的意思是,当你这样做时会发生什么:

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

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

【讨论】:

【参考方案4】:

尚不支持将其作为语言功能,因为这需要value types,因为通过引用传递堆栈数据并不安全。

但作为一种优化 (escape analysis),JVM 可能已经对包含固定大小的小型数组的局部变量执行此操作,但前提是它可以证明它没有逃脱本地/被调用者范围。也就是说,这只是一个运行时优化,而不是一些规范保证,因此很难依赖它。

【讨论】:

以上是关于使用堆栈空间的 Java 数组的主要内容,如果未能解决你的问题,请参考以下文章

Java中堆栈的区别

在进行 C 到 Intel x86 程序集转换时,堆栈上的数组分配占用的空间超过了所需的空间 [重复]

为啥编译器保留一点堆栈空间而不是整个数组大小?

为啥编译器保留一点堆栈空间而不是整个数组大小?

ccs5.5怎么看堆栈

在有足够空间的情况下加载到数组会导致堆栈粉碎?