当前位置: 代码迷 >> J2EE >> java的内存分配有关问题
  详细解决方案

java的内存分配有关问题

热度:309   发布时间:2016-04-17 23:46:52.0
java的内存分配问题
有一个自定义类:
class A{
        int a=0;
        int b=0;
        String s="abc";

        A a=null;
        A b=new A();

        public void f1(){
                A c=new A();
        }

        public void f2(){
                String s2="bcd";
        }
}
然后主函数main()中这样调用:
main(){
        A a=new A();
        a.f1();
        a.f2();
}

有以下问题请教:
1、主函数中,当执行A a=new A()时,我们知道,a相当于指针,被分配在栈中;new A()才是真正的对象,被分配在堆中。那么,a实例中的引用类型成员变量a和b此时如何分配内存的,分配在哪?指针和实例都在堆中吗?
另外,a实例中的字符串成员变量s是被分配在内存的哪个区域?常量区还是堆区?
2、当执行a.f2()语句时,字符串s2的值"bcd"是被分配在堆区,还是常量池?

请大神不吝赐教!
------解决方案--------------------
亲,不要太纠结~  哈哈  

我说说我的理解:

首先,你说的A实例中, 所有的变量名:a、b、c、s 包括后面的s2 都是在栈空间中的,它就是你说的一个指针,指向堆空间中的对象。

其次,就要弄起字符串的特殊之处了,字符串的话,他的创建,不光是在堆空间中创建一块区域,它还会在字符串池中创建一个对象。 然后由栈空间的指针指向他们。
------解决方案--------------------
1、主函数中,当执行A a=new A()时,我们知道,a相当于指针,被分配在栈中;new A()才是真正的对象,被分配在堆中。那么,a实例中的引用类型成员变量a和b此时如何分配内存的,分配在哪?指针和实例都在堆中吗?
对象在堆里,基础变量在栈里

另外,a实例中的字符串成员变量s是被分配在内存的哪个区域?常量区还是堆区?
这个字符串是预赋值的,相当于常量,在常量池,也就是方法区里
2、当执行a.f2()语句时,字符串s2的值"bcd"是被分配在堆区,还是常量池?
但凡你在代码里看到的="string"这种类型的东西,全部都在常量池里
------解决方案--------------------
首先了解一下对象的内存布局,(以HotSpot虚拟机为例子)主要分为:
1.对象头,主要是对象自己运行时数据(包括hashCode、gc分代年龄、线程持有的锁、锁状态标识等等)和对象的类型;
2.实例数据,是对象真正有效数据;
3.对齐填充,用于占位符;
===============================================================================================

1、主函数中,当执行A a=new A()时,我们知道,a相当于指针,被分配在栈中;new A()才是真正的对象,
     被分配在堆中。那么,a实例中的引用类型成员变量a和b此时如何分配内存的,分配在哪?指针和实例都在堆中吗?
     另外,a实例中的字符串成员变量s是被分配在内存的哪个区域?常量区还是堆区?

答:
1.a实例中怎么会出现名称相同的字段(a和b)?
2.a实例的a和b.无是基本类型还是引用类型都在堆中,只是他们指向的值或对象可能是堆中也可能在常量池中;
3.成员变量s也是在堆,s指向的常量池中的常量"bcd"的地址
=============================================================
2、当执行a.f2()语句时,字符串s2的值"bcd"是被分配在堆区,还是常量池?
答:"bcd"是在常量池中,而s2是在栈中;

------解决方案--------------------
引用:
Quote: 引用:

所以A实例中s是分配到栈空间的,而他的值"abc"是在堆空间和字符串池的。

同理  字符串s2的值"bcd"是被分配在堆区和字符串池了。。

兄弟,你的最后一句话有问题的。
经过我自己的研究,“bcd”应该是被分配在了常量池中,不再分配到堆中。


恩恩,你自己有理解就好,不一定我的就是对的,我只是说说我的理解
------解决方案--------------------
引用:
Quote: 引用:

1、主函数中,当执行A a=new A()时,我们知道,a相当于指针,被分配在栈中;new A()才是真正的对象,被分配在堆中。那么,a实例中的引用类型成员变量a和b此时如何分配内存的,分配在哪?指针和实例都在堆中吗?
对象在堆里,基础变量在栈里


兄弟,你确定当执行new A()时,a实例中的类型成员变量a和b是在栈中被分配的?你要注意,a和b不是在main函数中直接声明的,而是类的成员变量啊……
其实,我可以把意思说的更明白些:
如果类与类之间出现了组合关系时,当调用类被实例化时,被引用类的指针或者说引用符号,到底是在栈中还是堆中分配的?注意:被引用的类,并非是直接在函数中定义的局部变量。特请注意!!!!

sorry,没看清-_-#,.成员变量全在堆里没错,这个我的说法有问题。

方法体里的变量指针在栈里,只出现在方法运行时
------解决方案--------------------
学习学习一下
------解决方案--------------------
Good investigation
------解决方案--------------------
引用:
刚刚测了一下,还真是会造成循环引用,结果直接撑爆堆区了。


运行后:

恩,自己多测试,能更好的理解相关的理论知识,另外建议可以使用jconsole来观察整个虚拟机的内存变化,jconsole会显示堆和方法区的内存使用情况和变化,也能检测出死锁或资源耗尽的问题。
------解决方案--------------------
这个类有问题
------解决方案--------------------
不同的Java虚拟机有不同的实现.
------解决方案--------------------
learning
------解决方案--------------------
JAVA还未入门
------解决方案--------------------
java还未入门
------解决方案--------------------
  相关解决方案