每当我在java中发起一个列表时,我都会这样做
List<Integer> list = new LinkedList<>();
Run Code Online (Sandbox Code Playgroud)
我假设这将在堆上分配列表.不知道我是否可以在堆栈上分配列表?
所有对象(包括其各自的属性)都存储在堆上.
所有局部变量及其参数都存储在堆栈中,因为它们包含原始值或引用.
但是,在特殊情况下,java虚拟机可能会执行转义分析并决定LinkedList在堆栈上分配对象(包括您的对象),但这通常不会发生,也不是主要问题.
作为一般规则,如果在堆栈上分配对象,则在调用引用它的函数时将获得该对象的副本.相反,如果在堆上分配对象,当您将指针传递给对象时,您将获得指针的副本(指向堆上的同一对象).
理论上,JVM实现可以使用"转义分析"在堆栈上分配对象.如果可以确定对创建的对象的引用永远不会从堆栈中泄漏,则JVM可以在堆栈而不是堆上分配它.这样做的好处是减少垃圾收集开销; 当退出堆栈帧时,可以立即回收该内存.由于参考的局部性,它也可能提高速度.
从Java 7开始,在Oracle的HotSpot Java运行时中引入了转义分析.通过此增强功能,HotSpot可以选择不分配未修改的堆栈本地对象; 它不是在堆栈上分配它们,而是完全删除分配.虽然这可以避免堆栈分配,但它确实证明了这些事情是允许的运行时优化.
但是,Java程序员无法直接控制此行为.这是JIT编译器执行的优化.我不确定语言规范是否允许在编译时进行这种优化.它可能,但我没有研究过它.