Java为了提高程序的运行效率,堆数据进行了不同的空间分配

◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中

在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。即存放的是局部变量

当在一段代码块定义一个变量时,Java就在栈中 为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

◆堆:存放用new产生的数据

堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理

◆小例子1

在函数中定义一个数组

int[] arr = new int[3];

内存中:

java堆内存分析工具 java堆内存分配_数组

java堆内存分析工具 java堆内存分配_内存分配_02

◆◆◆◆◆◆堆特点一:在堆中,每一个new出来的对象都有一个地址值(一般是一个16进制的对象),堆再把这个值赋值给栈中的局部变量。堆和栈就通过这个地址联系起来。

java堆内存分析工具 java堆内存分配_java_03

所以我们直接打印arr,输出的是地址。

System.out.println(arr);

输出结果: [I@15db9742

◆◆◆◆◆◆堆特点二:堆中每个变量都有默认值

比如数组:arr[0],arr[1],arr[2] 默认值为0

◆◆◆◆◆◆堆特点三:堆中使用完毕就变成了垃圾,但是没有立即回收,会在垃圾回收器中回收

◆◆◆◆◆◆栈特点:栈内存中的数据使用完就释放(脱离作用域后,比如函数结束)

◆小例子2

定义3个数组

//定义第一个数组
        int[] arr = new int[3];
        arr[0] = 88;
        arr[1] = 33;
        arr[2] = 66;
        System.out.println(arr);
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
        System.out.println("----");

        //定义第二个数组
        int[] arr2 = new int[3];
        arr2[0] = 22;
        arr2[1] = 44;
        arr2[2] = 55;
        System.out.println(arr2);
        System.out.println(arr2[0]);
        System.out.println(arr2[1]);
        System.out.println(arr2[2]);
        System.out.println("----");

        //定义第三个数组
        int[] arr3 =  arr;
        arr3[0] = 100;
        arr3[1] = 200;
        System.out.println(arr);
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);

执行结果:

java堆内存分析工具 java堆内存分配_System_04

栈内存的两个引用指向了堆内存的同一个引用,无论是谁的操作,都是操作的堆中的同一地址。

java堆内存分析工具 java堆内存分配_java_05

二维数组的内存分布

java堆内存分析工具 java堆内存分配_数组_06