JVM内存
- JVM中主要的三块内存空间:
1. 栈内存
2. 堆内存
3. 方法区 - 除了这三块之外,还有其他的
- 方法区:类加载器classloader,将硬盘上的xxx.class字节码文件装载到JVM的时候,会将字节码文件存放到方法区当中,也就是说方法区中存储的是代码片段,因为类需要加载,所以方法区当中是最先有数据的
- 栈内存:在方法被调用的时候,该方法需要的内存空间以及栈中方法的局部变量在栈中分配,并且调用时就是压栈,方法执行结束之后,该方法所需要的空间就会释放,此时发生弹栈
- 方法调用:压栈,分配空间
- 方法结束:弹栈,释放空间
- 方法不调用的话,是不会在栈中分配空间的
- 栈数据结构:先进后出,后进先出
package com.ycy;
public class Demo {
public static void main(String[] args) {
System.out.println("main begin");
int x = 100;
m1(x);
System.out.println("main over");
}
public static void m1(int i){
System.out.println("m1 begin");
m2(i);
System.out.println("m1 over");
}
public static void m2(int i){
System.out.println("m2 begin");
m3(i);
System.out.println("m2 over");
}
public static void m3(int i){
System.out.println("m3 begin");
System.out.println(i);
System.out.println("m3 over");
}
}
/*最后的结果是
main begin
m1 begin
m2 begin
m3 begin
100
m3 over
m2 over
m1 over
main over
*/
-
堆内存:
- 凡是通过new运算符创建的对象,都存储在堆内存当中,new运算符的作用就是在堆内存中开辟一块空间
- 堆内存中存储对象,以及对象的实例变量
public class Demo {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
// s1和s2叫做引用
System.out.println(s1.name);
System.out.println(s1.NO);
System.out.println(s1.age);
System.out.println(s1.sex);
System.out.println(s1.addr);
}
}
--------------------------------------------------------------------------------------------------------------------------------
public class Student {
int NO;
String name;
int age;
boolean sex;
String addr;
}
- 为什么要画内存图
- 有了内存图,程序不运行也可以知道结果
- 有助于调试程序
- 这是对java运行机制的理解,否则出现复杂的程序错误就不会调试
内存图作业
public class Demo {
public static void main(String[] args) {
User u = new User();
Address a = new Address();
a.city = "温州";
a.zipcode = "325401";
a.street = "技校街0";
u.id =00000;
u.name = "张三";
u.password = "123456";
u.address = a;
System.out.println(u.id);
System.out.println(u.name);
System.out.println(u.password);
System.out.println(u.address.city);
}
}
--------------------------------------------------------------------------------------------------------------------------------
public class Address {
String city;
String street;
String zipcode; //邮编
}
--------------------------------------------------------------------------------------------------------------------------------
public class User {
int id;
String name;
String password;
Address address;
}
--------------------------------------------------------------------------------------------------------------------------------
- int是一种基本数据类型
- String是一种引用数据类型
- Address是我们自己写的,也是一种引用数据类型
- id, name, password, address 都是实例变量 ,都在堆内存的对象内部
- u.address.city代码可以拆分理解
- int i = u.id 可以理解
- Address x = u.address (u.address是Address类型,因为在User类里面有Address address代码)
- String y = x.city
- u.address.city可以节省变量
对象和引用怎么区分?
- 对象是推里new出来的
- 引用是储存对象内存地址的一个变量
- new xxx 这个xxx是一个对象
- 类型 x = new 类型 这个x是一个引用
引用一定是局部变量吗?
不是的
这里的address是引用,因为address保存了变量的内存地址,但是它在堆里,是成员变量