Java中的堆、栈、方法区深入分析

基本概念

堆区:
1.
存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm
只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身。
栈区:
1.
每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中。
2.
每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.
栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)
方法区:
1.
又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的classstatic变量。
2.
方法区中包含的都是在整个程序中永远唯一的元素,如classstatic变量。

说明:这里对象与内存地址是相对关系,对象引用指的是对象在内存中的地址。

数据类型分为基本数据类型和引用数据类型,如图


具体案例如下:


public class Test1 {
    public static final int s=1;
    
    public static void main(String[] args) {
            int t=1;

//这里的A类已在同一个包下创建好了。

            A a1 = new A();
            System.out.println(t);
            System.out.println(s);
            System.out.println(a1);
    }

}

运行结果为:

1
1
test.A@6e1408

这个案例分为三种情况:

第一种为 int t=1;

           这条语句应该分解为两个步骤:

          int t;//我们结合上述概念,这句是告诉JVM在运行期间该线程中的私有栈中为变量t分配一个存放内存地址的空间。

          t=1;//这一步,JVM判断1为基本数据类型,则在该私有栈中查字面值为1的地址,如果没有则创建该地址,并且该地址为私有栈内部变量共享,就是其他内部变量值也为1的话,就不需要再在该私有栈中创建1的地址,返回给变量t的就是私有栈内的地址。输出结果为1是根据JVM内部规则运行的,这里注意一点1这个地址在私有栈内是唯一。

第二种为  public static final int s=1;

           这条语句就一个步骤:

           public static final int s=1;//这句是告诉JVM在编译期间就在该线程中的私有栈中为变量t分配一个存放内存地址的固定空间,并由于是static及int修饰的,并已经赋值,则在该私有栈中直接为1分配一个固定空间,地址反馈给t,相当于t这个变量及1这个基本数据类型均固定不能更改任何特性,直到该线程结束,也就是在编译期均已经确定,运行期对其无法更改。

           这里public static final int s;//这句就与上面的不一样,分为编译期与运行期,编译期就是在该线程中的私有栈中为变量t分配一个存放内存地址的固定空间,由于是static及int修饰的,则被指定赋值为0,直到运行期初始化时,可以通过被赋值来改变指向的对象,也就是说变量t一直无法改变其空间位置,而其内的对象地址可以更改。

第三种 为    A a1 = new A();

              我们也分为两步:

              A a1;//JVM在该线程中的私有栈中为变量t分配一个存放内存地址的空间,该空间的值是无法确定的,需要被初始化才能知道。

             a1 = new A();//JVM先判断数据类型,是引用数据类型,则在方法区中查询 A()的class原码,如果没有则返回错误,但一般都是已经加载进内存的了,正常情况下均会找到,找到了后,在堆中根据class大小分配内存空间(堆是动态分配内存空间的),然后拷贝一份A()的class到该空间中,这里可以明白如果A()的class内的某个变量被赋值,方法区内的该变量还是保持原来的状态,改变的只是堆中的class拷贝,也就是实例化后的对象。然后返回堆中的内存地址给私有栈。这里的输出结果不是1而是test.A@6e1408这个内存地址,这可能是JVM内部的运行机制,以后再细细研究。这里可以看出堆中的对象是无法共享的,因为即使是同一个class的拷贝,运行中其成员变量可以被赋予不同的值,这就无法共享了。


以上是详细讲解java创建对象的三个基本过程,以供参考,具体JVM为什么一下输出具体值,一下又输出内存地址,有人知道吗?


联系方式:379877741@qq.com



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值