【发布时间】:2009-08-30 18:43:30
【问题描述】:
在java中可以同时使用静态内存分配和动态内存分配来创建对象吗?
【问题讨论】:
-
您对“静态”和“动态”内存分配的具体含义是什么?
标签: java object memory-management
在java中可以同时使用静态内存分配和动态内存分配来创建对象吗?
【问题讨论】:
标签: java object memory-management
如果通过静态内存,您的意思是在堆栈上,不,所有对象都在堆上分配。堆栈上只分配原语。
编辑:我仍然不确定动态和静态是否分别是指堆和堆栈,但这通常是具有 C/C++ 背景的人的问题所在,因为这些语言让开发人员可以控制那个。
在Java中,当你做一个典型的:
Object o = new Object();
这将在堆上分配内存。如果在一个方法中你这样做:
int i = 1;
然后那个 int 被分配到栈上(如果是类中的一个字段,那么它会被分配到堆上)。
【讨论】:
所有实例内存(通过调用new)都在堆上分配,所有参数都在栈上分配。但是java(非原始)参数都是通过引用(异常原始)传递的。
【讨论】:
“静态”并不意味着“在堆栈上”。
在类静态变量的初始化或static code blocks 中分配的对象是静态分配的,因为分配是在类加载时完成的(可以在程序启动后立即静态发生)。
理论上,你可以编写一个只使用这种分配的 java 程序,它会是statically allocated,就像一个从不调用 malloc 的 C 程序一样,只是为它想要做的事情提供了固定的缓冲区。
如果这样的程序成功启动,则证明有足够的内存可供它执行所有操作,因此它永远不会出现内存不足错误、碎片问题或 GC 暂停。
如果写得正确,它只会返回很多错误消息,说“我不能那样做”。
【讨论】:
声称总是在堆上分配非基元的答案是完全错误的。
JVM 可以使用escape analysis 来确定对象是否总是被限制在单个线程中,以及对象的生命周期是否受给定堆栈帧的生命周期的限制。如果它可以确定一个对象可以在堆栈上分配,JVM 可能会在那里分配它。
详情请见this article。
【讨论】: