一个简单的全局变量与局部变量问题

bangyulin 2009-09-30 04:16:49



public class A{

//在栈中创建b引用
//在堆中创建一个B的对象
//b引用指向B对象
private B b = new B();
//在栈中创建c引用
private C c ;

public void createC(){

//在堆中创建一个B的对象,
//修改b的引用,使引用指向它
c = new C();

}
public D createD(){

//在栈中创建d引用
//在堆中创建一个D的对象
//d引用指向D对象
D d = new D();
}

public static void main(String[] args){

//在栈中创建a引用
//在堆中创建一个A的对象
//a引用指向A对象
A a = new A();
a.createC();
a.createD();

/*
问题?
b与c变量数据全局的,所以会比d存活的久一点
那堆中的B、C、D对象的生命周期一样长吗?
*/

}


...全文
102 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
bangyulin 2009-09-30
  • 打赏
  • 举报
回复
谢谢楼上做的测试
bigbro001 2009-09-30
  • 打赏
  • 举报
回复
运行程序后,只有D的对象被回收了,其他的都没有被回收。。。

public class A{

private B b = new B();
private C c ;

public void createC(){
c = new C();
}

public void createD(){
D d = new D();
}

public void finalize()
{
System.out.println("Finalizing A.");
}

public static void main(String[] args){
A a = new A();
a.createC();
a.createD();
while(true)
System.gc();
}
}

class B
{
public void finalize()
{
System.out.println("Finalizing B.");
}
}

class C
{
public void finalize()
{
System.out.println("Finalizing C.");
}
}

class D
{
public void finalize()
{
System.out.println("Finalizing D.");
}
}
siakang 2009-09-30
  • 打赏
  • 举报
回复
垃圾收集的发生具有不可预知性:由于实现了不同的垃圾收集算法和采用了不同的收集机制,所以它有可能是定时发生,有可能是当出现系统空闲CPU资源时发生,也有可能是和原始的垃圾收集一样,等到内存消耗出现极限时发生,这与垃圾收集器的选择和具体的设置都有关系.
垃圾回收机制进行回收时,若对象此时没有被引用,则会将该对象作为垃圾回收 ,具体什么时候回收,则需要看采用的是什么回收机制,总之一个原则:当一个对象变为无用对象时,就随时会被回收.
bigbro001 2009-09-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 bangyulin 的回复:]
按照垃圾回收机制。
我觉得应该是不会的。
垃圾回收在内存不够的情况下会提前启动
检测到B C D三对象的时候。由于B C 的引用属于全局的。所有一般不会立即回收
而d中的就不同。方法 createD执行结束后,d引用失效了。对D对象来说。它已经是个垃圾了
此时会被回收
[/Quote]

正解。。。等会儿写个程序验证,稍等片刻
AldisZhan 2009-09-30
  • 打赏
  • 举报
回复
ZangXT 大侠如是说
[Quote=引用 32 楼 zangxt 的回复:]
引用 30 楼 hz_haoyu 的回复:
Object o = new Object(); //线程执行到这里的时候,o的变量在哪里,new Object()在哪里?
static Object o = new Object(); //线程执行到这里的时候,o的变量在哪里,new Object()在哪里?

各在内存在栈、堆、方法区?
多谢。

关键:先区分引用和对象的实际关系。
每个线程有一个自己的栈。

Object o = new Object(); //线程执行到这里的时候,o的变量在哪里,new Object()在哪里?
如果该声明是在方法中的话,o是个局部引用变量(或者说就是指针,地址),存在于线程的栈里。实际对象在堆中。

如果该声明是在类定义中的话,
比如
class Test{
Object o = new Object();
}
o是个nonstatic field,引用o作为Test对象的一部分存在于堆中,而o指向的new Object 也在堆中,但不是上面提到的o所在Test对象的一部分。

static Object o = new Object();
o在方法区,实际对象在堆中。
[/Quote]
kingluchao 2009-09-30
  • 打赏
  • 举报
回复
其实简单的东东蕴含大智慧啊
YU1983826 2009-09-30
  • 打赏
  • 举报
回复
java实战上考虑这个没什么大用,如果是个人兴趣的话,同意楼上的建议。
AldisZhan 2009-09-30
  • 打赏
  • 举报
回复
楼主可没有弄清 JVM中 heap 和 stack 的机理
被一些书给误导了 有些书说 引用就在栈中 对象生成就在堆中 这是片面的
建议楼主可看一下这贴
http://topic.csdn.net/u/20090927/15/e5bcd2aa-a70e-44d6-aa66-1d6d4a8783e1.html
里面讨论了一些 关于JVM stack 和 heap 的机理
弘石 2009-09-30
  • 打赏
  • 举报
回复
楼主如果对这些问题敢兴趣的话,强烈推荐楼主看Thinking in java
一洽客服系统 2009-09-30
  • 打赏
  • 举报
回复
重写finalize方法输出下 看看 D对象是不是在创建完发现没有引用就回收了呢
bangyulin 2009-09-30
  • 打赏
  • 举报
回复
按照垃圾回收机制。
我觉得应该是不会的。
垃圾回收在内存不够的情况下会提前启动
检测到B C D三对象的时候。由于B C 的引用属于全局的。所有一般不会立即回收
而d中的就不同。方法 createD执行结束后,d引用失效了。对D对象来说。它已经是个垃圾了
此时会被回收
designedIt 2009-09-30
  • 打赏
  • 举报
回复
我是菜鸟,我看楼主与我一样菜啊。首先要分清:对象是对象,引用是引用,不一样的啊。你要问的倒底是对象还是引用啊?
999朵玫瑰 2009-09-30
  • 打赏
  • 举报
回复
会啊

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧