繁体   English   中英

为什么Java使用堆进行内存分配?

[英]Why does Java uses heap for memory allocation?

我刚刚在一本java书中读到这句话,说java中的Objects驻留在堆上。 是否使用了堆,因为它是存储数据和快速检索数据的最佳方式?

我只是想知道数据结构是初学者。 我的意思是为什么不堆叠或其他东西?

堆栈的问题是您只能删除最近添加的内容。 这适用于局部变量,因为它们在您进入和退出函数时来来往往,但对于生命周期不遵循单个函数的任意数据则不太好。 内存堆允许您随意添加和删除数据。

堆仅由vm用于分配和释放内存块。 要访问那里的对象,您可以使用对内存块的引用(该引用位于堆栈中)。 jvm不允许直接访问内存(如在C / C ++中)。

它是底层计算模型的工件。 操作系统的内存看起来像一个大的,大部分是连续的空间,可以通过地址读取和写入数据。 操作系统允许进程通过使用内存地址和读/写操作来获取一块内存(一个大的连续空间,通常至少是一对K的一页)并按照自己的意愿来处理。

java堆构建在它上面,即对于程序员来说,它看起来就像一大包内存(当然不是,即垃圾收集通常会移动东西),他得到了“地址”(实际上,引用它们实际上并不是写入此内存空间的数据(对象)。 这使您可以最大程度地灵活地构建更专业的数据结构。

请记住,它对程序员来说就像一个“堆”,因为它允许您具有必要的灵活性,但它不必如此实现。 它是由垃圾收集器管理的一块内存,它有一堆数据结构用于完成它的工作,你可以或不可以考虑它的一部分,即它是由JVM使用和分配的内存,但通常只有程序员可访问的内存才被认为是此上下文中的“堆”。

因为Java使用垃圾收集器来回收内存,这与C和C ++不同。 在这些语言中,将堆栈用于局部变量*是有意义的。 在Java中,没有(本地)变量超出范围的概念,只有它不再被引用,这使得它有资格进行垃圾收集(这必然会在该点之后的某个时间发生)。

*为了清楚起见,这并不意味着C / C ++中没有堆,或者您不能使用malloc / new系列来分配仅在本地范围内使用的变量。

为什么不在堆栈上存储对象? 那么,当前执行的方法停止执行后,堆栈会发生什么?

因为Java中的对象通常比创建它们的范围更长,所以为该范围创建的堆栈帧不再存在。

当创建对象的范围不再存在时,相反的分配堆空间不会自动解除分配。

Java可以在堆栈上存储对象,如果它确实转义分析 ,确定方法返回时非本地对象不保留对该对象的引用。 它不允许您声明对象存储在堆栈中。

如果Java确实允许在堆栈上显式显示对象,那么当方法返回时会发生什么? 任何非本地对象持有的对本地对象的任何引用会发生什么?

  • Java设计者可能已经确定某些引用可能无效 ,如果取消引用则会导致未定义的行为。 就像C / C ++中的指针一样。 Java设计者似乎已经竭尽全力避免未定义的行为。

  • Java设计者可以指定对本地对象的所有引用都变为null。 找到所有这些参考文献会很困难。 并且它将导致难以发现由假定为非null的引用突然变为null的错误。 包含对象引用的不可变对象是不可能的。 并且设置对null的引用的通知机制必须跨线程工作。 所有这些的成本远远高于本地存储的优势。

  • 语言设计师之一James Gosling有一个Lisp背景,这种影响在对象处理只留给垃圾收集器的想法中可见,如果可能的话,编译器或运行时环境优化对象处理(转义分析)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM