[英]Runtime vs compile time memory allocation in java
关于java中的内存分配是在运行时还是编译时发生,我感到很困惑。
例如:
class Test{
int a;
public Test(){
a=10;
}
};
// somewhere else
Test t = new Test();
是a
在运行时或在编译时分配的? 如果在编译时,如果java在直接获取编译的.class文件的VM上运行,那怎么可能呢?
也:
当a
分配值10
?
它如何用于参考变量t
?
谢谢。
编译时不会发生内存分配。 仅在加载和运行时。
编译时会生成.class文件。
请记住,您需要有一个主类来运行该程序。 使用带有classpath到.class文件的Java运行程序时,会出现加载和链接等步骤,
类加载器将文件加载到permgen。
当调用main方法时,将创建堆栈并将局部变量放在那里
当运行时遇到new时,它会在堆上创建对象并在那里分配所需的内存,就像Test所需的内存一样。
局部变量和方法参数(例如基元或引用)在编译时在概念上被分配在堆栈上的一个位置。
在运行时,无法保证能够反映它在内存中的布局方式。
堆上对象的分配仅在运行时发生。
如何在VM上直接运行compile .class文件运行java。
只有VM知道如何编译代码,因此无法在编译时进行内存分配。
when是指定值10
在分配发生的行。 鉴于它没有被使用,JIT可以丢弃它,因此根本不会发生。
同样的问题代表参考变量t。
t
被指定在构造对象之后=
位置。
嗯,这个有点像doozy,我不确定你是否会从这整个帖子中得到你想要的确切答案,因为真的,你所要求的,是一个主要的话语。编译器的内部,大多数人真的不在乎。
在大多数情况下,Java编译器使用自动内存管理,因此编译器确定它将要或不会做什么,这可以在版本之间进行更改。
但在我开始解释之前,我想澄清我的注意事项:
String是java中的一个特例,虽然它是一个对象,但它的处理方式可能与其他对象不同。
[object]具有特殊属性。 它具有值和标识符,以及将标识符解析为值并在何时发生的过程取决于绑定的类型。
存在静态绑定,其中绑定可以在编译时解析,并且其值或方法在编译时是已知的。 这也称为“早期”绑定。 例如。
int a = 0; // AND //直接函数调用,如print();
还有动态绑定,其中标识符和值或子程序之间的绑定直到运行时才能发生。 这也称为“晚期”绑定。 例如。
public void foo(java.util.List list){list.add(“bar”); }
还有一种混合类型的绑定,但我不打算谈论它,因为我没有发现Java有它。
现在,绑定也与范围非常密切相关,范围是变量“存在”某个范围内的想法。 这是一个话题,我真的不想进入(范围是一种熊),并使这篇文章成为小说而不是中篇小说。
Java中内存分配的工作方式取决于以下几点:
如果在编译时已知对[Object],[object]或[primitive]的引用,并且可能发生静态绑定,那么编译器可能会为这些对象分配内存(注意我是怎么做的)在编译时使用括号)。
如果在编译时无法知道对[Object],[object]或[primitive]的引用,并且必须使用动态绑定,则编译器可能会在运行时为这些对象分配内存。
Java处理在运行时分配的对象的方式区分取决于使用哪种类型的绑定。
总之,不要担心。 你这样做很头疼。
如果我对此有任何不对,请有人告诉我。 我有点生疏了。
在java中,除非创建了在运行时创建的对象,否则不会加载类,因此任何成员变量(如“a”)都会在加载类时获得空间。对于对象,它将在运行时分配空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.