为什么Java没有';不允许堆栈上的对象? 我在爪哇学习C++课程背景下的一些课程和对象课程。我想知道为什么我们不能选择要在堆栈内存中声明的对象?为什么除了基本类型之外,所有的东西都必须放在堆上

为什么Java没有';不允许堆栈上的对象? 我在爪哇学习C++课程背景下的一些课程和对象课程。我想知道为什么我们不能选择要在堆栈内存中声明的对象?为什么除了基本类型之外,所有的东西都必须放在堆上,java,heap-memory,stack-memory,Java,Heap Memory,Stack Memory,我想澄清一下我的问题 基本上,如果我们有: 扫描仪输入=新扫描仪(System.in) 那为什么我们不能把它放在堆栈上呢 为什么除了基本类型之外,所有的东西都必须放在堆上 这种说法不准确。如果基元类型是类实例的一部分,它们也可以放在堆上。局部变量存储在堆栈上,其中as类变量位于堆上 至于为什么对象存储在堆上。这毕竟是一个设计决定。一个原因是,它是JVM中受垃圾收集约束的托管区域。作为JVM中的一个受管区域,它可以按代组织,并且可以在大小上增长或缩小。请参阅JVM规范: Java虚拟机有一个在所有

我想澄清一下我的问题

基本上,如果我们有:

扫描仪输入=新扫描仪(System.in)

那为什么我们不能把它放在堆栈上呢

为什么除了基本类型之外,所有的东西都必须放在堆上

这种说法不准确。如果基元类型是类实例的一部分,它们也可以放在堆上。局部变量存储在堆栈上,其中as类变量位于堆上

至于为什么对象存储在堆上。这毕竟是一个设计决定。一个原因是,它是JVM中受垃圾收集约束的托管区域。作为JVM中的一个受管区域,它可以按代组织,并且可以在大小上增长或缩小。请参阅JVM规范:

Java虚拟机有一个在所有Java虚拟机线程之间共享的堆。堆是运行时数据区域,所有类实例和数组的内存都是从该区域分配的

堆是在虚拟机启动时创建的。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收;对象永远不会显式解除分配

为什么除了基本类型之外,所有的东西都必须放在堆上

这种说法不准确。如果基元类型是类实例的一部分,它们也可以放在堆上。局部变量存储在堆栈上,其中as类变量位于堆上

至于为什么对象存储在堆上。这毕竟是一个设计决定。一个原因是,它是JVM中受垃圾收集约束的托管区域。作为JVM中的一个受管区域,它可以按代组织,并且可以在大小上增长或缩小。请参阅JVM规范:

Java虚拟机有一个在所有Java虚拟机线程之间共享的堆。堆是运行时数据区域,所有类实例和数组的内存都是从该区域分配的

堆是在虚拟机启动时创建的。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收;对象永远不会显式解除分配


堆栈上的数据(比如C结构)在函数调用返回后消失。因此,需要复制和更正指针。 想想这里需要隐藏的额外功能:

struct S* f() {
     struct S s = ...;
     g(&s);
     return &s;
}
Java的意思是简化,拥有自己的内存管理,在堆上立即做事情看起来更直接,更不复杂


这是C++的,它有复制构造函数、指针和别名。

< P>栈上的数据,比如C结构,在函数调用返回后消失。因此,需要复制和更正指针。 想想这里需要隐藏的额外功能:

struct S* f() {
     struct S s = ...;
     g(&s);
     return &s;
}
Java的意思是简化,拥有自己的内存管理,在堆上立即做事情看起来更直接,更不复杂


这是C++的,它有拷贝构造函数、指针和别名。

< P>原始java设计中最强的吸引子(在20世纪90年代中期)是简单的。支持基于堆的对象是必要的,而基于堆栈的对象是一种优化。Java并不是这里唯一的语言:许多语言都采用这种方法(LISP、Haskell、JavaScript、Ruby等)。基于堆栈的分配确实在Java中发生,但只是作为一种内部优化技巧,而不是用户可以控制的东西

尤其要记住,被调用方处理传递给函数的对象指针(“传递给方法的引用”在Java speak中)的方式有本质的区别:如果指针是基于堆栈的,则不允许保留指针。这本身就造成了巨大的复杂性和bug机会


最后,基于堆栈的对象比垃圾管理语言对C语言和C++语言的管理要小得多。

< P>原始java设计中最强大的吸引子(在20世纪90年代中期)是简单的。支持基于堆的对象是必要的,而基于堆栈的对象是一种优化。Java并不是这里唯一的语言:许多语言都采用这种方法(LISP、Haskell、JavaScript、Ruby等)。基于堆栈的分配确实在Java中发生,但只是作为一种内部优化技巧,而不是用户可以控制的东西

尤其要记住,被调用方处理传递给函数的对象指针(“传递给方法的引用”在Java speak中)的方式有本质的区别:如果指针是基于堆栈的,则不允许保留指针。这本身就造成了巨大的复杂性和bug机会


最后,基于堆栈的对象比垃圾管理语言对手工收集的语言(如C和C++)所带来的影响要小得多。

java不允许对象的显式堆栈分配。该语言不与C等低级语言竞争,语言的创造者将此选择作为一种简化

然而,时代在变化,Java从它卑微的起步就已经发展起来了。随着JVM变得越来越复杂,自动将对象分配到堆栈已成为可能。其原理类似于C中的“register”关键字;让编译器管理底层细节。它比人类做得更好。在Java中,对象在堆栈上的自动分配受到两个因素的阻碍,首先,Sun/Oracle JVM非常旧,现在非常复杂。这是很难改变的,Oracle一直在谨慎地防止向后中断。其次,到目前为止,他们在堆栈分配方面的工作还没有产生预期的巨大效益。