在平时我们都会直接使用数组,编者也是,但是数组中的内存相关的知识也是需要了解的,今天就一起来学习一下吧!
首先我们知道Java中的数据类型可以分为基本数据类型和引用数据类型,那么在引用数据类型中就有比如类、接口、枚举等等,当然数组也是一种重要的引用数据类型。
什么是引用数据类型呢?简单来说,引用数据类型中存储的是对实际数据的引用,这些数据通常存储在堆内存中。
同学们之前肯定已经听说过堆栈了吧,那么我们现在就以数组为切入口,了解一下有关引用数据类型的知识。
一、初始JVM的内存分布
内存是一段连续的存储空间,主要用来存储程序运行时数据的。
JVM对所使用的内存按照功能的不用进行了划分。
• 程序计数器(PC Register):只是一个很小的空间,保存下一条执行的指令的地址。
• 虚拟机栈(JVM Stack):与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了。
• 本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似,只不过保存的内容是Native方法的局部变量,在有些版本的JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的。
• 堆(Heap):JVM所管理的最大内存区域,使用 new 创建的对象都是在堆上保存,堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。
• 方法区(Method Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,方法编译出的的字节码就是保存在这个区域。
当然对于现在数组的学习,我们只简单关心堆和虚拟机栈这两块空间。
二、引用类型变量
不同于基本数据类型创建的基本变量,变量空间中直接存放的是其所对应的值,而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。
比如上述代码,a,b,arr,都是方法内部的变量(局部变量),因此其空间都在main方法对应的栈帧中分配。a,b是内置类型的变量,因此其空间中保存的就是给该变量初始化的值。arr是数组类型的引用变量,其内部保存的内容可以简单理解成是数组在堆空间中的首地址。
就如上图,通过引用变量中的地址,引用变量便可以去操作对象。有点类似C语言中的指针,但Java中引用要比指针的操作更简单。
三、再谈引用
1.两个引用可以通过【=】来进行引用指向的转移。比如arr1 = arr2,就表示让arr1去引用arr2引用的数组的空间,此时arr1和arr2实际就是一个数组。
2.null在Java中表示“空引用”,也就是一个不指向对象的引用,表示一个无效的内存地址。注意不能对这个内存进行任何读写操作。一旦尝试读写,就会抛出NullPointerException异常。
3.如果传参时传的是数组类型,由上图我们可以发现,在func方法内部修改数组的内容,方法外部的数组内容也发生改变。这是因为数组是引用类型,按照引用类型来进行传递,是可以修改其中存放的内容的。
总结:所谓“引用”,本质上只是存放了一个地址。Java将数组设定成引用类型,这样的话后续进行数组参数传参,其实只是将数组的地址传入到函数形参中,这样避免对整个数组的拷贝。
以上就是关于数组的一些知识,如果哪里讲的不对希望大家能够指出,谢谢大家的阅读。可以的话,点赞+关注呗!