Java内存分析个人理解
因为初学Java,学过的知识点容易忘记,所以最近在复习以前学过的东西,刚好复习到类和对象的概念,产生了疑问。
- 疑问一:
Person p1 = new Person();
在第一遍学习的时候,一直以为p1就是对象,经过复习纠正错误
new Person()才是一个新的对象,在Java中都是先创建一个对象然后再来使用这个对象,这个p1是对new Person()这个对象的一个引用,相当于c语言里面的一个指针,可以说成是new Person()的地址,“=”不存在一个赋值的过程,只能算作一个传递地址的过程。
在这里简单的做一下内存分析:
- 疑问二
按照这个理解,我写了如下代码:
package object_equal;
/*
* 对于new的理解
*/
public class ObjectEqual {
public static void main(String[] args) {
Person p1 = new Person();
Person p3 = new Person();
p3 = p1;
Person p2 = p1;
p1.age = 10_0000;
System.out.println(p1.age);
p2.age = 11;
System.out.println(p1.age);
System.out.println(p3.age);
p3.age = 167;
System.out.println(p1.age);
System.out.println(p2.age);
p1.action();
p2.action();
}
}
class Person{
int age;
public void action() {
System.out.println("我能唱跳rap篮球");
}
}
运行结果如下:
解释如下:class Person中的变量和方法以及class ObjectEqual中的main方法都在方法区中,在程序运行的时候,首先main方法最先进入栈中开始执行。
创建第一个对象,p1进入栈中,并且在堆中开辟空间,从方法区中拿出变量,赋初值,也就是age = 0,同时将方法区中存放action方法的地址保存到堆中并且把新开辟的堆空间的地址赋给栈中的p1.
在创建一个对象,p3进入栈中,并且在堆中开辟空间,从方法区中拿出变量,赋初值age = 0,同时将方法区中存放action方法的地址保存到堆中(这里的地址值与创建第一个对象的地址值相同)并且把新开辟的堆空间的地址赋给栈中的p3.
这部我理解成一个赋地址值的操作,就是将p1指向的堆空间的地址赋给了p3,而p3原本指向的那块空间就变为垃圾空间在下次JVM回收之前如果还是没有被栈内存指向,就会被JVM回收。如下图所示:
接下来执行的Person p2 = p1;我认为只是一个地址赋值的过程将p1指向的堆空间的地址给了p2,但是因为p2没有new所以在堆中并没有开辟新的空间。
理解到这里,往下的运行过程就可以理解了
- 疑问3
常量在内存中的位置
第一种,static的,作为类信息在类被加载时被存在静态的方法区,没毛病。
第二种,非static的,作为对象属性,在对象创建的时候被初始化,存在堆里,没毛病。
第三种,在方法里的。我们知道在方法被调用时会被加载到栈中进行执行,所以写在方法里的变量存在栈中。 - 以上理解可能有不正确的地方,希望大佬纠正。