Java静态变量声明时候初始化该变量与放在构造器中初始化该变量有何区别?JVM堆栈和C/C++堆栈的关系是什么样
本人Java弱鸡①枚,最近看项目代码,无意中看到了单例模式,突然有点深思,而之前自学反射的时候,也写过类似的代码,却报了错误,所以傻傻的有点分不清.看到结果,也不知道所以然,为何大相径庭,凭着印象,代码如下:
当对象实例化放在构造器中执行:
报出栈内存(之前写的为堆内存,算是自己笔误,虽然知道stack表示栈,但是潜意识认为是堆内存被堆满,已修改....)不足,之前写出这样的代码,认为很正常不过了,构造器中不断的递归嵌套,在实例化的时候,会产生①个新的Test,Test中的实例变量进行实例化,又产生①个新的,如此往复.
但是,如此执行却不会报错:
意料之外的是竟然没有造成内存泄漏.因为之前看到①个帖子,Java不断创建静态变量是可以堆满方法区造成内存泄漏的,至于这个为什么不会造成java.lang.OutOfMemoryError,请大腿们指点①下~
而且,按照我的理解,Java中实例变量中的初始化和赋值是在构造器中执行的.
既然如此,为何两片代码看起来相似,执行结果却大相径庭?还望大腿们指点①下,不胜感激
On the bytecode level, static field members will be compiled into block while normal field members will be compiled into constructor. Static field will be initialized during class loader, while a normal field initialization will be conduct on its constructor.
For example:
Class hello{ int data; flags: static java.lang.String a; flags: ACC_STATIC public hello(); // flags: ACC_PUBLIC Code: stack=① · locals=① · args_size=① ⓪: aload_⓪ ①: invokespecial #① // Method java/lang/Object.\"\":()V ④: aload_⓪ ⑤: iconst_⑤ ⑥: putfield #② // Field data:I ⑦: return LineNumberTable: line ①: ⓪ static {}; // This is for static variable initialization. flags: ACC_STATIC Code: stack=① · locals=⓪ · args_size=⓪ ⓪: ldc #② // String message ②: putstatic #③ // Field a:Ljava/lang/String; ⑤: return LineNumberTable: line ③: ⓪}
挑几个主要代码给楼主看:
① · java的堆在c++代码中有专门的对象与之对应,然后分成年轻年老带
class ParallelScavengeHeap : public CollectedHeap {
private:
static PSYoungGen* _young_gen;
static PSOldGen* _old_gen;
}
年轻带分成了③部分,_eden_space,_from_space,_to_space
class PSYoungGen : public CHeapObj {
protected:
MutableSpace* _eden_space;
MutableSpace* _from_space;
MutableSpace* _to_space;
}
年老带只有①个space
class PSOldGen : public CHeapObj {
protected:
MutableSpace* _object_space; // Where all the objects live
}
space里有①个top指针,指向开头。。。。。这片内存有很大。。。。
class MutableSpace: public ImmutableSpace {
protected:
HeapWord* _top;
}
看的出来java的内存被jvm虚化了,。。。。。
栈也是①个,栈帧被jvm虚拟化的对象叫frame
class frame : public _ValueObj {
private:
// Instance variables:
intptr_t* _sp; // stack pointer (from Thread::last_Java_sp)
address _pc; // program counter (the next instruction after the call)
CodeBlob* _cb; // CodeBlob that \"owns\" pc
}
c++要内存就跟操作系统new呗,
java要内存就跟c++new,只不过java的new出来的东西,都被c++维护起来了。。。。。
- 5星
- 4星
- 3星
- 2星
- 1星
- 暂无评论信息