首先要整体了解jvm原理,运行一个java程序,jvm就存在了一个实例,对应一个堆,可JVM内存可分为heap,stack,method,应用程序运行中的所创建的所有类实例
或数组都放在这个堆里,首先LZ这个程序,系统一旦收到我们指令,启动了java虚拟机进程,寻找classpath中 Z.java的Z.class文件,读取二进制数据,因此把Z类的信息
放在运行数据时的方法区,接着java虚拟机定位Z类的main()方法的字节码,此方法执行语句new Z() ,在栈区查找对象引用Z的地址,若没有自动配置内存地址,再开辟堆区,并默认初始化,而此类是继承结构,开始先执行父类 X,若有 静态代码块,先执行,若没有,则进行构造,又开始执行 new Y(),在栈区开始查找对象应用B的地址,若没有自动配置内存地址,开辟了堆区并初始化值,接着执行y的构造 结果xyz
注意,我看了毕老师这方面的视频,但讲解了不全面,一旦出现很难看出了bug,花费精力更多,
1.栈区存放了基本类型数据,执行环境上文,操作指令,与方法区调用方法启动每个线程包含一个栈区,每个方法的参数若是基本类型也放在栈区
最近学习碰到了一下怪题,String str1="abc" ; string str2="abc" str==str2 这里注意 int,float,boolean,等基本数据类型的包装类型封装了,不能修改栈区内部值 也包括String
举个例子int a=3 ,int b=3 a==3 上面遇到了怪题跟这个很相似,因为字面量a 在栈区分配的内存地址,而字面量b的时候开始在栈区查找地址,所以共同引用的这个地址
所以str1==str2 确实成立,一般在包装类型比较引用类型用equals()方法,一旦修改,就改变指向了就false了
2.方法区就是静态区,跟堆一样,被所有线程共享了,包含了class和staitc变量
3.堆区存放都是对象,每个对象都包含一个对应的class信息,并且heap被所有线程共享
|