Java原始对象实例化:堆与否?

Posted

技术标签:

【中文标题】Java原始对象实例化:堆与否?【英文标题】:Java primitive object instanciation: heap or not? 【发布时间】:2012-07-11 07:49:05 【问题描述】:

所以我在读这本书时说,如果我创建一个 Point 类,然后通过 Point p1 = new Point(); 实例化它,那么我将拥有:

堆上的一个 Point 对象(作为“new”关键字的结果); 对此对象的引用 (p1); 当一个对象没有引用时,它可以被垃圾收集器处理掉。

我想我明白了意思,但它让我思考。原始类型和字符串在“内存方面”会发生什么,即:

 - int x1 = 100;
 - String s1 = "hello";

 - int x2 = new Integer(100);
 - String s2 = new String("hello");

在第一种情况下,'100' 和 'hello' 会被实例化并存储在堆上吗?否则,x1 和 s1 引用的是什么?

谢谢!

【问题讨论】:

可能重复:Does the Java primitives go on the Stack or the Heap? 字符串不是原语,Integer 也不是。但是int 是。 我知道,这就是我区分“原始类型和字符串”的原因,我的问题特别针对 x1 和 s1。 【参考方案1】:

首先:

 int x2 = new Integer(100);

这意味着一个Integer 对象被创建、出箱(JVM 返回它的intValue)并且100 分配给一个int 原语。 Integer 对象不再被引用并且可以被释放(当然也许 JIT 可以将其优化为 int x2 = 100)。

我假设您在谈论局部变量,因为属性是对象的一部分,因此位于堆中。

 int x1 = 100;

在栈中声明一个int变量并赋值

 String s1 = "Hello";

一个字符串对象被创建(或被引用,参见String.intern())并且一个指针被添加到堆栈中。

其他可能性完全相同。

【讨论】:

谢谢你,它让它更清楚了。还有一个问题(但也许它应该有自己的帖子): - 属于对象的方法呢?他们也和它在一起吗?我很难弄清楚我的程序的记忆是如何“组织”的...... 方法是类定义的一部分(它本身就是类java.lang.Class的对象)。当您加载类 A 时,会使用所有方法信息创建对象 Class A,但是当您实例化类 A 的对象时,其方法不需要额外的空间。当您执行其中一个对象方法时,JVM 会转到 Class A 对象并从中检索代码,而不是从 A 的每个实例中检索。【参考方案2】:

本地原语将被放入堆栈,但对象的成员字段将与该对象一起放入堆中(无论它是否是原始的)。更多信息here。

字符串是对象并且存在于堆上。不过,它们的工作方式确实有点不同,一些信息here。

【讨论】:

【参考方案3】:

S1 和 S2 都会在存储值的位置创建新的内存引用。根据具体情况,原始数据类型可能指的是堆栈或堆。你可以看看here

【讨论】:

以上是关于Java原始对象实例化:堆与否?的主要内容,如果未能解决你的问题,请参考以下文章

Java对象的实例化过程

实例化,掌握栈与堆内存的关系

Java面向对象---类与对象的关系

实例化,掌握栈与堆内存的关系(转)

46栈内存溢出内存区域(程序计数器Java 虚拟机栈本地方法栈Java 堆方法区直接内存内存溢出)与内存溢出(对象实例化分析)

栈跟堆个人简介整理