Java原始对象实例化:堆与否?
Posted
技术标签:
【中文标题】Java原始对象实例化:堆与否?【英文标题】:Java primitive object instanciation: heap or not? 【发布时间】:2012-07-11 07:49:05 【问题描述】:所以我在读这本书时说,如果我创建一个 Point 类,然后通过 Point p1 = new Point();
实例化它,那么我将拥有:
我想我明白了意思,但它让我思考。原始类型和字符串在“内存方面”会发生什么,即:
- 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原始对象实例化:堆与否?的主要内容,如果未能解决你的问题,请参考以下文章
46栈内存溢出内存区域(程序计数器Java 虚拟机栈本地方法栈Java 堆方法区直接内存内存溢出)与内存溢出(对象实例化分析)