java变量存放在栈中还是存放在堆中?
栈内存:某一个函数被调用时,这个函数会在栈内存里面申请一片空间,以后在这个函数内部定义的变量,都会分配到这个函数所申请到的栈。当函数运行结束时,分配给函数的栈空间被收回,在这个函数中被定义的变量也随之被释放和消失。
堆内存:通过new产生的数组和对象分配在堆内存中。堆内存中分配的内存,由JVM提供的GC(垃圾回收机制)来管理。在堆内存中产生了一个数组对象后,我们还可以在栈中定义一个变量,这个栈中变量的取值等于堆中对象的首地址。栈内存中的变量就成了堆内存中数组或者对象的引用变量。我们以后就可以在程序中直接使用栈中的这个变量来访问我们在堆中分配的数组或者对象,引用变量相当于数组或者对象起的一个别名,或者代号。
引用变量是一个普通的变量,定义时在栈中分配;引用变量在被运行到它的作用域之外时就被释放,而我们的数组和对象本身是在堆中分配的,即使程序运行到使用new产生对象的语句所在的函数或者代码之后,我们刚才被产生的数组和对象也不会被释放。数组和对象只是在没有引用变量指向它,也就是没有任何引用变量的值等于它的首地址,它才会变成垃圾不会被使用,但是它任然占据着内存空间不放(这也就是我们Java比较吃内存的一个原因),在随后一个不确定的时间被垃圾回收器收走。
String存放在堆中还是栈中?
堆和栈是JAVA程序在运行过程中的数据存储区,栈是stack,堆是heap。
堆主要用来存储使用new关键字创建的J***a对象和数据,堆中存储的对象和数据都有相应的内存地址值。当堆中存储的对象和数据不再被使用时,J***a的JVM会启动垃圾回收机制,自动清除堆中存储的对象和数据。
栈是用来存储临时数据的,如J***a对象的引用,函数内部的数据和临时对象,函数执行完毕后,存储在栈中的临时数据会立即被释放。
问题中的String指的应该是j***a中的String吧。这里给出的回答针对j***a。
String是一个不可变的对象,在j***a中只能作为常量使用。j***a代码中所有的显式字符串,即直接写出的那种字符串,例如"abc"都是String对象。String本身作为一个对象,必然是在堆上的,而String中的内容char[] value 则是放在堆中的一个特殊区域中——常量区。
所以String本身是放在堆上,而根据垃圾回收情况,又可以分为新生代和老年代。如果这个String对象刚创建不久,则它一般位于堆的新生代,如果它创建之后存在了很长时间,则它很可能处于堆中的老年代。注意,String中的字符串内容即字符数组value则位于堆中的常量区。
如果你先有一个字符数组,例如char[] arr { 'a', 'b', 'c' },然后调用String s = new String(arr);创建的String,则字符数组不再是位于常量区,而是跟其他对象一样,位于堆上。注意,即使这个arr数组是在栈上分配的,这样创建的String中的value依然是在堆上。如果你想把这个字符串放进常量区,可以调用String.intern。
栈上不会有对象,只会有基本变量和引用变量,所以String只可能位于堆上,不可能位于栈上。