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

时间:2021-05-24 10:28:36



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对象的生命周期一样长吗?
     */

  }


13 个解决方案

#1


会啊

#2


我是菜鸟,我看楼主与我一样菜啊。首先要分清:对象是对象,引用是引用,不一样的啊。你要问的倒底是对象还是引用啊?

#3


按照垃圾回收机制。
我觉得应该是不会的。
垃圾回收在内存不够的情况下会提前启动
检测到B C D三对象的时候。由于B C 的引用属于全局的。所有一般不会立即回收
而d中的就不同。方法 createD执行结束后,d引用失效了。对D对象来说。它已经是个垃圾了
此时会被回收

#4


重写finalize方法输出下 看看 D对象是不是在创建完发现没有引用就回收了呢 

#5


楼主如果对这些问题敢兴趣的话,强烈推荐楼主看Thinking in java

#6


楼主可没有弄清 JVM中 heap 和 stack 的机理
被一些书给误导了 有些书说 引用就在栈中 对象生成就在堆中 这是片面的 
建议楼主可看一下这贴
http://topic.csdn.net/u/20090927/15/e5bcd2aa-a70e-44d6-aa66-1d6d4a8783e1.html
里面讨论了一些 关于JVM stack 和 heap 的机理

#7


java实战上考虑这个没什么大用,如果是个人兴趣的话,同意楼上的建议。

#8


其实简单的东东蕴含大智慧啊

#9


ZangXT 大侠如是说 
引用 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在方法区,实际对象在堆中。

#10


引用 3 楼 bangyulin 的回复:
按照垃圾回收机制。
我觉得应该是不会的。
垃圾回收在内存不够的情况下会提前启动
检测到B C D三对象的时候。由于B C 的引用属于全局的。所有一般不会立即回收
而d中的就不同。方法 createD执行结束后,d引用失效了。对D对象来说。它已经是个垃圾了
此时会被回收


正解。。。等会儿写个程序验证,稍等片刻

#11


垃圾收集的发生具有不可预知性:由于实现了不同的垃圾收集算法和采用了不同的收集机制,所以它有可能是定时发生,有可能是当出现系统空闲CPU资源时发生,也有可能是和原始的垃圾收集一样,等到内存消耗出现极限时发生,这与垃圾收集器的选择和具体的设置都有关系.
垃圾回收机制进行回收时,若对象此时没有被引用,则会将该对象作为垃圾回收 ,具体什么时候回收,则需要看采用的是什么回收机制,总之一个原则:当一个对象变为无用对象时,就随时会被回收.

#12


运行程序后,只有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.");
  }
}

#13


谢谢楼上做的测试

#1


会啊

#2


我是菜鸟,我看楼主与我一样菜啊。首先要分清:对象是对象,引用是引用,不一样的啊。你要问的倒底是对象还是引用啊?

#3


按照垃圾回收机制。
我觉得应该是不会的。
垃圾回收在内存不够的情况下会提前启动
检测到B C D三对象的时候。由于B C 的引用属于全局的。所有一般不会立即回收
而d中的就不同。方法 createD执行结束后,d引用失效了。对D对象来说。它已经是个垃圾了
此时会被回收

#4


重写finalize方法输出下 看看 D对象是不是在创建完发现没有引用就回收了呢 

#5


楼主如果对这些问题敢兴趣的话,强烈推荐楼主看Thinking in java

#6


楼主可没有弄清 JVM中 heap 和 stack 的机理
被一些书给误导了 有些书说 引用就在栈中 对象生成就在堆中 这是片面的 
建议楼主可看一下这贴
http://topic.csdn.net/u/20090927/15/e5bcd2aa-a70e-44d6-aa66-1d6d4a8783e1.html
里面讨论了一些 关于JVM stack 和 heap 的机理

#7


java实战上考虑这个没什么大用,如果是个人兴趣的话,同意楼上的建议。

#8


其实简单的东东蕴含大智慧啊

#9


ZangXT 大侠如是说 
引用 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在方法区,实际对象在堆中。

#10


引用 3 楼 bangyulin 的回复:
按照垃圾回收机制。
我觉得应该是不会的。
垃圾回收在内存不够的情况下会提前启动
检测到B C D三对象的时候。由于B C 的引用属于全局的。所有一般不会立即回收
而d中的就不同。方法 createD执行结束后,d引用失效了。对D对象来说。它已经是个垃圾了
此时会被回收


正解。。。等会儿写个程序验证,稍等片刻

#11


垃圾收集的发生具有不可预知性:由于实现了不同的垃圾收集算法和采用了不同的收集机制,所以它有可能是定时发生,有可能是当出现系统空闲CPU资源时发生,也有可能是和原始的垃圾收集一样,等到内存消耗出现极限时发生,这与垃圾收集器的选择和具体的设置都有关系.
垃圾回收机制进行回收时,若对象此时没有被引用,则会将该对象作为垃圾回收 ,具体什么时候回收,则需要看采用的是什么回收机制,总之一个原则:当一个对象变为无用对象时,就随时会被回收.

#12


运行程序后,只有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.");
  }
}

#13


谢谢楼上做的测试