kanon 发表于 2014-12-10 00:26:49

JAVA中实例化一个对象,成员方法中的参数会在哪分配内存(...

本帖最后由 kanon 于 2014-12-10 00:28 编辑

声明 仅仅是收集整理的

我所知道的局部变量和常量值都是放在stack的,而data segment是存放静态变量,为什么会有这样的差异?(也看到过说,对象的引用是存放在stack的,个人感觉这样应该不对,如果该变量是一个类的非静态成员的话应该是放在heap里的。局部变量是不是只有main里面的才算局部?)stack中的数据都是生命周期明确的,data segment中的数据有什么特性需要特别存放呢?静态方法和非静态方法都是存放在code segment中的,除了调用方法不同以外还有什么区别么?

首先内存总体分为了4个部分,包括 stack segment、heap segment、code segment 、data segment ;
Stack segment: 局部变量,新new的对象的引用,数组引用等。
heap segment: new出来的东西实际分配的内存在这里,还有数组的元素等。这些局部变量是在具体方法执行结束之后,系统自动释放内存资源.
code segment: 加载的.class文件放在这里(补充 网上的另一个答案是 程序中的方法,是内存中的code segment中的,而且是多个对象 共享一个代码空间区域)
data segment: 常量,静态变量等。



对象引用都是在栈里的,相当于C/C++的指针,new出来的对象实例才是在堆里的,局部变量。。什么叫局部?一般就是一个块语句,一个函数体里面的所定义的变量,data segment一般存放常量和静态常量,方法,函数什么的都是放在code segment ,静态方法通过类名操作,非静态方法通过对象引用操作。


追问
对象引用都是在栈里的?如果一个class T{String s;}那创建一个T对象,s的引用就应该放在堆里才对啊。我想,在java里用局部变量这个词也不好,因为没有全局这概念。不过你的解释使我理解了局部变量的生命周期是已经明确了的。data segment是放常量的么?我以前看别人说是放在栈里的,不过你的解释比较正确的样子,毕竟常量一直存在于整个周期,不需要对它销毁。那data segment的空间是固定的吧?静态变量的话那会是放在哪里呢?

回答
对象句柄啊= =,你听过没?就是对象引用
String s = new String("Hello world");
这句代码s 就是对象引用(也叫对象句柄)
后面new的就是在堆里分配
你的class T{String s;}这里类T里面声明一个String类的对象引用s(注意,这里只是声明!!还没有new出来,此时s的默认值还是null,它只是一个类似指针概念的东西,都是放在栈里的)
既然对象引用是存放在栈里面的,那它的生命周期如何?
栈的特点就是先进后出,存储内容小,所以一般的对象引用都会在函数调用结束时就销毁了
data segment那个不太清楚,只知道存放常量和静态的

追问
不好意思啊,我比较啰嗦= =。我意思是,s是T的一个数据成员,当T t=new T();会生成一个对象存放在堆里面,并且对t.s=newString("123");之后,存放在堆里的对象指的应该只是某个类的数据成员,所以s的值应该是放在堆里的吧。毕竟,我们还不知道t的对象何时该销毁,也就是s的值何时该销毁我们也不知道。假设t是在method()里生成的,并且该方法返回了t所指的对象。t所指对象该何去何从是method()所不知道的,因此s所指对象也不知

回答
你想太多了= =,记住一点就行,只要是对象句柄(引用),都是在栈,只要是new的都是在堆,至于对象句柄什么时候被销毁?我问你,你是不是在某个函数(或主函数)里面声明这个类的实例啊,那它的作用域也就很明显啊,就是在这个函数的范围内









Person per1=new Person();

这句话实际是做了三件事情



第一:类型Person 对象名per1
先是声明了一个此类型的引用对象名称。

第二:new 类型()//new Person();
在内存中分配空间,调用构造初始化

第三:把第一中声明的引用名称与初始化得对象关联。


重复单调〃 发表于 2015-7-29 13:06:19

页: [1]
查看完整版本: JAVA中实例化一个对象,成员方法中的参数会在哪分配内存(...