对象创建内存(主要对栈和堆的理解)

对象创建内存(主要对栈和堆的理解)

JAVA在程序运行时,在内存中划分5片空间进行数据的存储。分别是:1:栈。2:堆。3:方法区
4:寄存器 5:本地方法栈

目录

1:栈。
2:堆。
3:方法区
4:寄存器
5:本地方法栈
6:栈和堆实例分析

1. 栈。

定义
Java栈的区域很小 , 大概2m左右 , 特点是存取的速度特别快

栈存储的特点是, 先进后出

存储速度快的原因: 

栈内存, 通过 '栈指针' 来创建空间与释放空间 !

指针向下移动, 会分配新的内存, 向上移动, 会释放这些内存 !

这种方式速度特别快 , 仅次于PC寄存器 !

但是这种移动的方式, 必须要明确移动的大小与范围 , 

明确大小与范围是为了方便指针的移动 , 这是一个对于数据存储的限制, 存储的数据大小是固定的 , 影响了程序 的灵活性 ~

所以我们把更大部分的数据 存储到了堆内存中 
总结
栈 存贮 基本数据类型,对象引用变量
栈 大小范围固定 
栈内存特点,数数据一执行完毕,变量会立即释放,节约内存空间, 速度快。
栈内存中的数据,没有默认初始化值,需要手动设置。    

1. 堆。

定义
Java 中 堆 是 一种通用的内存池,用于存放所有Java 对象。
new关键字, 是指告诉JVM , 需要明确的去创建一个新的对象 , 去开辟一块新的堆内存空间,
与栈不同 ,优点在于我们创建对象时 , 不必关注堆内存中需要开辟多少存储空间 , 也不需要关注内存占用 时长 !
缺点 开辟内存及清理相对栈要更多时间
总结
堆内存用来存放new创建的对象和数组。
堆  没有固定大小范围限制 用法灵活但速度较慢
堆内存中所有的实体都有内存地址值。
堆内存中的实体是用来封装数据的,这些数据都有默认初始化值。
堆内存中的实体不再被指向时,JVM启动垃圾回收机制,自动清除

3. 方法区

定义
存放
	类信息,静态变量,常量,成员方法
方法区中包含了一个特殊的区域 ( 常量池 )(存储的是使用static修饰的成员)

4. PC寄存器

定义
PC寄存器保存的是 当前正在执行的 JVM指令的 地址 !
 
在Java程序中, 每个线程启动时, 都会创建一个PC寄存器 ! 

5. PC寄存器

定义
保存本地 native 方法的地址

6. 栈和堆实例分析

例1
基本数据类型赋值与方法调用(基本数据类型的包装类型与基本类型一样)

    public static void main(String[] args) {
        int a=0;
        test(a);
        System.out.println(a);
    }

    static void test( int a){
       a=1;
       System.out.println(a);
    }

输出

1
0

分析

第1步——main()方法是程序入口,JVM先执行,在栈内存中开辟一个空间,存放int类型变量a,同时附值0。
第2步——JVM执行test(a)方法,在栈内存中又开辟一个新的空间, 存放int类型变量a,同时附值1。
     此时main空间与test空间并存,互不影响。
第3步——test()执行完毕,变量a立即释放,空间消失。但是main()函数空间仍存在,main中的变量a仍然存在,不受影响。
在这里插入图片描述

例2

 public static void main(String[] args) {
        MyInt a=new MyInt();
        a.setValue(0);
        test(a);
        System.out.println(a.getValue());
    }

    static void test( MyInt a){
       a.setValue(1);
       System.out.println(a.getValue());
    }

    static class MyInt{
        public int value;
        public int getValue() {
            return value;
        }
        public void setValue(int value) {
            this.value = value;
        }
    }

输出

1
1

分析

第1步——main()方法是程序入口,JVM先执行,
	在栈内存中开辟一个空间,存放a变量(x变量是局部变量),在堆内存中开辟一个空间,存放new MyInt()对象  存放堆内存地址  假如为:0x01 并将这个地址赋值给变量 a ,这时变量a 就指向了new MyInt()对象 的堆内存空间 。
第2步——main() 中执行 a.setValue(0)
  即在 堆内存的对象空间中将0 赋值给 value这个属性。
第3步——JVM执行test(a)方法,在栈内存中又开辟一个新的空间, 存放变量a,同时附值 0x01 也指向。
	    
第4步——test(a)方法 中执行 a.setValue(1)
  即在0x88这个内存地址的 堆内存中将1 赋值给 value这个属性。
第5步——test()执行完毕,变量a立即释放,栈空间消失,但堆内存仍然存在,main中的变量a仍然指向0x01这个堆内存的内存地址。
main()和方法test() 同时对 堆内存中的值操作相互影响

在这里插入图片描述

例2

    public static void main(String[] args) {
        int [] a= new int [1];
        a[0]=0;
        test2(a);
        System.out.println(a[0]);
    }

    static void test2( int [] a){
        a[0]=1;
       System.out.println(a[0]);
    }

输出

1
1

分析

同例2 数组也是堆内存会相互影响
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值