1 一个对象的内存
面向对象-07-三种情况的对象内存图_哔哩哔哩_bilibili
(1)加载class文件
(2)声明局部变量
(3)在堆内存中开辟一个空间
(4)初始化(默认/显式)
(5)构造方法初始化
(6)将堆内存中的地址值赋值给左边的局部变量
①栈:方法运行时进栈,执行完毕出栈
②堆:new出来的对象都在堆里
③方法区:临时存储字节码.class文件
详细过程:
开始执行测试类TestStudent,将字节码文件TestStudent.class加载在方法区中,同时在TestStudent.class文件中会有main()方法的临时存储
虚拟机自动调用main()方法,main()方法会加载在栈内存中
然后执行第一行代码Student s = new Student(),用到类Student会将字节码文件Student.class加载在方法区中,同时进行所有成员变量和成员方法的临时存储;首先执行Student s,声明局部变量s;然后执行new Student(),在堆内存中开辟一个地址值为001的空间,将所有成员变量拷贝到此地址,将成员方法地址存入此地址;之后进行默认初始化,String name默认为null,int age默认为0;因为new Student()括号里没有参数,所以调用的是空参构造,而此空参构造中没有语句,所以构造方法初始化已完成;最后将堆内存中的地址值001赋值给左边的局部变量s
输出s也即输出s的地址值001
......
通过s调用study()方法,在堆内存对应的地址中找到study()方法的地址,通过此地址找到方法区中的study()方法,此时study()方法加载进栈,study()执行完毕后,study()出栈,main()出栈,变量s消失,不再使用地址值为001的空间,此时此空间从堆内存中消失变成垃圾
注意:
当JVM内存不足时,启动垃圾回收
垃圾回收处理器 -- 垃圾回收处理机制是Java语言区别于其他语言的内在的核心 , 不需要手动的处理JVM中无用的数据
拓展:
(1)this的本质:方法调用者的地址值
(2)字符串
使用双引号直接赋值时,系统检测该字符串在串池(StringTable)里是否存在(串池在堆内存中),不存在则创建新的,存在则复用
String s1 = "abc"; //串池中没有"abc",则会在内开辟一个空间存储"abc"(0x0011)
String s2 = "abc"; //串池中已经有"abc"(0x0011)
String s3 = new String("abc"); //只要有new,就会在堆内存中开辟空间(0x0022)
String s4 = new String("abc"); //只要有new,就会在堆内存中开辟空间(0x0033)
Scanner sc = new Scanner(System.in);
String s5 = sc.next(); //键盘录入相当于new出来的,会在堆内存中开辟空间(0x0044)
(3)调用方法时,参数的传递:
实参是引用数据类型,栈中的main( )从堆中找到引用数据类型变量的地址传递给fun( ),操作时需要到指定的地址中获取;实参是基本数据类型时,在栈中,main获得方法的数据传给fun( )
综上所述:
使用String s1 = "abc"直接赋值比String s3 = new String("abc")节省空间
2 JVM虚拟机
java代码在JVM虚拟机中运行,运行步骤:
-
编写.java文件
-
通过javac编译为.class文件
-
执行.class文件
3 equals和==
equals比较内容,==比较地址