今天突然产生一个疑问,之前接受的概念如下:
Arm arm = new Arm();
给一个变量new一个对象,arm是放在栈里的, new Arm()是存放在堆里,还说局部变量和函数参数都是放在栈里的,
可是Java是面向对象,所有的代码都承载物都是对象(这种情况下,变量和参数不都应该放在堆里么?)或者main函数(这种情况下放在栈里
,那难道这个概念只针对入口函数么?)
举例:
public class Human {
int age;
Arm arm;
public Human() {
age = 0;
arm = new Arm();
}
public static void main(String[] args) {
Human p = new Human();
p.getArm().bend();
}
}
这里p放在栈里我可以理解,那age和arm会放在堆里还是栈里呢?我好迷惑
(1)理论上Java面向对象,所以一切皆为对象,问题是,如果真的是如此,连整数都是对象,那么性能太低了。
所以实际上简单类型不是对象,Java中这些叫做值类型,值类型只有在需要被看作对象的时候才像个对象,这个过程叫装箱。
(2)Arm arm = new Arm();arm是一个引用,如果这行代码在函数内,那么arm在堆栈上,而指向的那个对象,包括对象内的成员,无论是不是值类型,则都在堆上。
(3)agr arm肯定都在堆上,因为它们属于Human这个对象,而这个对象只能在堆上。
只有一种情况在堆栈上,就是变量本身是简单类型(值类型),并且变量是函数的局部变量(而不是类的成员)。
首先
Arm arm = new Arm();
这里有两个事物:变量arm、新建出来的Arm对象实例。
对象实例是肯定放在堆上面的。
变量分两种情况:类成员变量在堆上,函数内的局部变量在栈上。
其实很好记,成员变量跟随对象实例,一个实例对应一份,堆;函数变量跟随函数的调用,而函数可以多次调用,每次调用都是用栈的。
我说的是arm这个引用本身在堆栈上,而它指向的对象永远在堆上。
楼主记住一点,=号左边的是变量声明,存在在栈中,=号右边的是实例,存放在堆中,包括实例的类变量。
栈中一般存放的是指向堆中某块区域的地址值,堆中存放的是实例。
栈使用的一级缓存,他们都是被调用时处于存储空间中,调用完毕立即释放。
堆存放在二级缓存,生命周期由垃圾回收算法来决定什么时候释放。
看完1楼的回答我就绝望了,一知半解不研究情况就来误导人。。。
lz找本inside jvm看看吧,好好研究下heap、java stack 、native stack、pc register 、 non-heap的作用自然就明白了