当前位置: 主页 > JAVA语言

java 栈内存 开辟数组-Java数组:内存与堆内存的区别栈内存和堆

发布时间:2023-06-09 16:09   浏览次数:次   作者:佚名

Java数组

在进入讲解主题“-栈内存与堆内存的区别”之前,先来讲解一下数组,所谓数组,就是若干个相同数据类型的元素按一定顺序排列的集合。

一维数组的定义:

数据类型[ ] 数组名;

数组名 = new 数据类型[个数];

针对于Java数组,Java语言把内存分为两种:-栈内存和堆内存。

栈内存:

在方法中定义的一些基本类型的变量和对象的引用变量都在方法的栈内存中分配,当在一段代码块中定义一个变量时,Java就在栈内存中为这个变量分配内存空间,当超出变量的作用域后,Java会自动释放掉为该变量所分配的内存空间。

堆内存:

堆内存用来存放 new 运算符创建的对象和数组,在堆中分配的内存,由Java虚拟机的自动垃级回收器来管理。在堆中创建了一个数组或对象后,同时还在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,引用变量实际上保存的是数组或对象在堆内存中的首地址(也称为对象的句柄),以后就可以在程序中使用栈的引用变量访问堆中的数组或对象。引用变量就相当于是为数组或对象起的一个名称。引用变量是普通的变量,定义时在找中分配,引用变量在程序运行到其作用域之外后被释放。而数组或对象本身在堆内存中分配,即使程序运行到使用new运算符创建数组或对象的语句所在的代码块之外,数组或对象本身所占据的内存也不会释放,数组或对象在没有引用变量指向它时,会变为垃圾,不能再被使用,但仍然占据内存空间不放,在随后一个不确定的时间被垃圾回收器收走(释放掉),这也是Java比较占内存的原因。

小结:

1 栈:为编译器自动分配和释放,如函数参数、局部变量、临时变量等等

2 堆:为成员分配和释放,由程序员自己申请、自己释放。否则发生内存泄露。典型为使用 new 申请的堆内容。

为了方便理解,举个例子:

如: int [ ] x; //定义了一个数组xjava 栈内存 开辟数组,这条语句执行完成后的内存状态如图1

x = new int [10]; //数组初始化,这条语句执行完成后的内存状态如图2

java用数组实现栈_java 栈内存 开辟数组_java 栈内存 开辟数组

图1.只声明了数组java 栈内存 开辟数组,而没有对其分配内存空间

java用数组实现栈_java 栈内存 开辟数组_java 栈内存 开辟数组

图2.声明数组并分配相应的内存空间,引用变量指向数据对象

执行第2条语句"x=new int [10];“后,在堆内存中创建了一个数组对象,为这个数组对象分配了10个整数单元,并将数组对象赋给了数组引用变量x,引用变量就相当于C语言中的指针变量,而数组对象就是指针变量指向的那个内存块。所以说在Java内部还是有指针的,只是把指针的概念对用户隐藏起来了,而用户所使用的是引用变量。

用户也可以改变x的值,让它指向另外一个数组对象,或者不指向任何数组对象。要想让x不指向任何数组对象,只需要将常量 null 赋给x即可。如x=null;,这条语句执行完后的内存状态如图3所示。

执行完"x=null;”,语句后,原来通过new int [10]产生的数组对象不再被任何引用变量所引用,变成了“孤儿”,也就成了垃圾,直到垃圾回收器来将它释放掉.

java用数组实现栈_java 栈内存 开辟数组_java 栈内存 开辟数组

图3.引用变量与引用对象断开

栈内存与堆内存的区别讲述完毕,迷路的你,是否看到了些许光芒。

为每一个不死心的明天而拼命的今天,都是2019年11月19日21点30分。

刚刚结束今天的马原期中,Java加油啊!