Java内存分配以及数组使用常见问题:

33 阅读3分钟

1. Java内存分配

memory:内存

不管是定义变量还是调用方法,一定是会消耗内存的。

不同区域干不同事情,容易管理容易维护,同时也可以提高性能!

  • 方法区 : 字节码文件加载时所进入的内存区域,class文件放在这里,相当于代码放在这里
  • 栈内存 : 方法运行时所进入的内存,变量也是在这里。main方法就是提取到栈内存里面运行的,方法的运行区,变量也是在这里的。
  • 堆内存 : new出来的东西会在这块内存中开辟空间并产生地址。也就是说所有new出来的东西都是放在堆内存里的。地址值它表示在堆内存当中的位置。我们一般把new出来的东西叫对象,对象就是一个东西。new出来的东西就是对象,也就是说所有对象会存在堆内存里。
  • 栈内存:方法运行的时候进栈,执行完毕出栈
  • 堆内存:new出来的对象都在这里
  • 方法区:加载字节码文件到方法区当中临时存储

由这三块区域来配合执行Java程序的。

基本数据类型的变量里面它存的就是数据本身。

而引用数据类型的变量它里面存的是右边对象地址。引用数据类型默认值为null。

程序具体在内存中是怎么去执行的?原理是什么样子呢?

  • 第一步先把这个类编译成 class 文件,加载到方法区里面去。
  • 第二步把 main 方法提取到我们的栈内存里面去运行。然后开始执行第一行代码。

java 的内存分配以及数组的内存图:

  • 在栈内存中去加载 arr 变量这个区域

2. 两个数组变量指向同一个数组对象

  • 在实际开发中还有一种数组内存图:两个变量变量指向同一个数组对象。
  • 有时候会把一个数组传给别人,别人也要拿一个变量去接这个数组,两个都是整型数组。
  • 同类型的变量可以赋值。
  • 把一个数组变量赋给另一个数组,赋的是数组对象的地址而不是数组对象本身。导致两个数组的地址一样。
  • 两个数组变量会指向同一个数组对象,访问的是同一个数组对象。
  • 通过地址去操作数组对象的内容。
  • 把一个数组变量赋值给另一个数组,赋的是数组对象的地址而不是数组对象本身,导致两个数组的地址一样。
  • 两个数组变量指向同一个数组对象,访问的是同一个数组对象,通过地址去操作数组对象的内容。

public static void main(String[] args) {
        int[] arr1 = {10,20,30,40};
        int[] arr2 = arr1;
        System.out.println(arr1 == arr2); // true
        arr2[1] = 10;
        System.out.println(arr1[1]); // 10
}

3. 数组使用常见问题

  • 问题1 : 如果访问的元素位置超过数组的最大索引,执行时会出现ArrayIndexOutOfBoundsException(数组索引越界异常)。
  • 问题2 : 如果数组变量中没有存储数组的地址,而是null,在访问数组信息时会出现NullPointerException(空指针异常)。
  public static void main(String[] args) {
        int[] arr = new int[] {10,20,30};
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
//        System.out.println(arr[3]); // 数组索引越界异常

        arr = null; // 数组变量不指向任何数组对象
        System.out.println(arr);
//        System.out.println(arr.length); // 空指针异常
    }