浅谈一个对象在java内存中的存放

Java内存划分的区域:

如果我们想要了解代码在Java中的存储方式,那么我们首先需要做的内存通常被分为个部分。Java中的内存通常被分为五个部分:

  1. 栈(stack)存放的都是方法中的局部变量
    局部变量:方法的参数或者是方法体({}内部的)变量
    作用域:局部变量作用域方法体内部,在下一个“}“后释放,即从栈内存中消失。
    (方法的运行一定要在栈中 )

  2. 堆(heap):凡是new出来的东西都储存在堆中
    堆内存里面的东西都有一个地址值:16进制
    堆内存里面的数据,都有一个默认值。
    堆中还开辟了一个小空间,专门用来存放字符串对象,叫做字符串常量池。
    整型:默认为0.
    浮点数:默认为0.0.
    字符型:默认为‘\u0000’(不可见字符)
    布尔型:默认为false
    引用类型:默认为null

  3. 方法区(method area):存储.class相关信息,包含方法的信息

  4. 本地方法栈(native method area):与操作系统相关

  5. 寄存器(PC register):与CPU相关

//一个简单的Java代码:
//在同一个包下
public class Student {
    String name;
    int age;

  public void homeWork(){
        System.out.println("写作业!");
    }

    public void gWork(String who){
        System.out.println("收"+who+"的作业!");
    }
}
public class DemoStudent {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.name = "郭靖";
        stu.age = 18;
        System.out.println(stu.name);
        System.out.println(stu.age);
        stu.homeWork();
        stu.gWork("黄蓉");
    }
}

(因为本人对寄存器和本地方法栈不太了解,所以今天的内容只涉及到三个区域,栈、堆和方法区。)
在运行main方法之前方法区要最先有数据:

方法区:
Student.class{
//成员变量
String name;
int age;
/成员方法
homeWork()
gWork()
}

DemoStudent.class{
main(String[] args)
}

因为程序是从main方法开始的,而所有方法想要运行就只能进栈,所以main方法先进栈(在这里有一个小知识点,在栈中先进后出)。

现在栈中:
从上面的代码可以知道,我们先new了一个对象;而等号左边就是一个局部变量(对象名称其实就是一个变量名称),等号右边相当于对它的一个赋值
main(String[] args){
Student stu (等号右边new了,而我们从上面可知new出来的都要在堆中)
……
}

堆中:
因为new了一个对象,所以在堆中开辟出一片空间
new Student()
//成员变量
//现在还没有赋值,所以它们都是默认值
String name; 默认值为:null
int age; 默认值为:0
//对于一个成员方法来说,它保存的其实是一个地址值
//当我们来创建对象时,方法区当中的成员方法的地址值就会放在堆当中
//成员方法(方法区当中的成员方法的地址值;如0x666)
}

而栈内main方法中的局部变量stu保存的就是堆当中new Student()的地址值(如0x999)
然后程序会继续向下运行:

栈中:
main(String[] args){
String stu   0x999;
stu.name = “郭靖”;
stu.age = 18;
//首先我们根据stu可以知道地址是多少,然后再根据地址值查找到name;因为我们现在给它赋值为郭靖,所以就将原来的null给替换掉了(age同理);
//然后使用两条打印语句,查看
//最后就是调用方法
stu.homeWork();
stu.gWork(“黄蓉”);
//拿stu.homeWork();举例;
//我们先从stu知道对象在堆中的地址值,然后在找到堆中成员方法中存放的发放区中的地址(也就是先找到0x999中的成员方法,然后在根据成员方法储存的0x666找到方法区中的成员方法。)

方法要运行要进栈,而栈的特点就是先进后出,所以后进来的方法会“压着”先进来的方法:

现在栈中:
homeWork(){
“写作业!”
}
main(String[] args){
String stu   0x999;
stu.name = “郭靖”;
stu.age = 18;
stu.homeWork();

而我们的方法在打印完“写作业”后,就完成了它的任务,这个时候它就会从栈中释放(stu.gWork(“黄蓉”);方法同理,只是需要传参给gWork()方法),在两个方法都执行完毕后,main方法释放,整个程序结束。

以上是现在对一个对象在java内存中的存放中的理解,如有不对,海涵!

你可能感兴趣的:(浅谈一个对象在java内存中的存放)