人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中?
这里浅谈Java中的栈和堆
首先,将结论写在前面,后面再用例子加以验证。
Java的栈中存储以下类型数据,栈对应的英文单词是Stack
基本类型
引用类型变量
方法
Java的堆中存储以下类型数据,堆对应的英文单词是Heap
实例对象
在函数中定义的一些基本类型的变量(8种)和对象的引用变量都是在函数的栈Stack内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
堆Heap内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。
引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!
class Person { int age; } public class LearnHeap { public static void main(String args[]){ int a=10; Person person = new Person(); person.age =20; change(a,person); System.out.println("a="+ a+",and person.age = "+person.age); } static void change(int a1, Person person){ a1 = 11; person.age= 21; System.out.println("a1="+ a1+",and age1 = "+person); } }
两次的输出结果是什么?猜测下。
实际输出如下:
结论:
如果a()方法中的基本类型(8个)变量x传入b()方法中,并在b()中进行了修改,则a()方法中的x的值保持不变
如果a()方法中的引用类型 变量x传入b()方法中,并在b()中进行了修改,则a()方法中的x的值与b()保持一致
下面对8中基本类型进行简单的测试
package heapandStack; public class LearnHeap02 { public static void main(String args[]){ byte b=10; short s=20; int i=30; long l =40l; float f =12.34f; double d = 100.123d; char c = ‘A‘; boolean flag = true; change(b,s,i,l,f,d,c,flag); System.out.println(b); System.out.println(s); System.out.println(i); System.out.println(l); System.out.println(f); System.out.println(d); System.out.println(c); System.out.println(flag); } static void change(byte a, short b, int c,long d, float f, double g, char h,boolean x){ a =11; b=21; c =31; d =41l; f=12.99f; g= 200.123d; h =‘V‘; x =false; System.out.println(a); System.out.println(b); System.out.println(c); System.out.println(d); System.out.println(f); System.out.println(g); System.out.println(h); System.out.println(x); } }
下面测试一下数组,是不是属于实例对象类型
public class LearnHeap03 { public static void main(String args[]){ int a[] ={1,2,3}; change(a); for(int i:a) System.out.print(i+" "); } static void change(int[] a){ a[0]=4; a[1]=5; for(int i:a) System.out.print(i+" "); System.out.println("============ "); } }
从结果看出,数组的值被改变了
原文:https://www.cnblogs.com/qianjinyan/p/10352749.html