偶然看到一道面试题,Java在实例化一个类的时候,数据在堆和栈中是如何存放的?
public class A{ public int i=1; public static A a1 = new A(); public static void mian(String args[]){ int c = 2; A a=new A(); } }
答案是:
处于栈中的数据:A对象的引用a和局部变量c
处于堆中的数据:变量a所指向的对象,变量a1所指向的对象,成员变量i,静态变量a1
Java的内存机制
Java把内存分为堆内存和栈内存两个部分
栈内存:
在 函数中定义的基本数据类型的变量和对象的引用都存放在栈内存,当在一个函数中定义一个变量时,java就在栈中为该变量分配内存空间,当这个变量被用完之后(超过了变量的作用域),java会自动释放掉为该变量分配的内存。因此我们可以这样理解,对于一个局部变量,如果它是一个基本数据类型,那么这个变量存放在栈中;如果这个变量是一个对象,那么该对象存放在堆中,而对象的引用仍然在栈中!
堆内存:
堆内存用来存放由 new 创建的对象和数组,所有的成员变量和static修饰的类变量,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。
当对象的引用在位于栈中时,栈中的这个引用的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量就相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/7800.html