当前位置:  开发笔记 > 编程语言 > 正文

怎么了java中的静态内存?

如何解决《怎么了java中的静态内存?》经验,为你挑选了2个好方法。

这个问题特别针对java语言.我知道为所有静态代码留出了一个静态的内存.

我的问题是这个静态内存是如何填充的?静态对象是在导入时还是在第一次引用时放入静态内存?此外,相同的垃圾收集规则是否适用于静态对象,因为它们适用于所有其他对象?

public class Example{
    public static SomeObject someO = new SomeObject();
}
/********************************/
// Is the static object put into static memory at this point?
import somepackage.Example;

public class MainApp{
    public static void main( Sting args[] ){
// Or is the static object put into memory at first reference?
       Example.someO.someMethod();
// Do the same garbage collection rules apply to a 
//     static object as they do all others?
       Example.someO = null;
       System.gc();
    }
}

erickson.. 34

导入与编译代码中的任何指令都不相关.它们仅在编译时建立别名.

有一些反射方法允许加载类但尚未初始化,但在大多数情况下,您可以假设每当引用类时,它都已初始化.

执行静态成员初始值设定项和静态块,就好像它们都是源代码顺序中的一个静态初始化程序块一样.

在卸载类之前,强引用通过静态成员变量引用的对象.正常ClassLoader从不卸载类,但应用程序服务器使用的类在正确的条件下执行.然而,这是一个棘手的领域,并且是许多难以诊断的内存泄漏的来源 - 这是不使用全局变量的另一个原因.


作为(切向)奖金,这是一个棘手的问题:

public class Foo {
  private static Foo instance = new Foo();
  private static final int DELTA = 6;
  private static int BASE = 7;
  private int x;
  private Foo() {
    x = BASE + DELTA;
  }
  public static void main(String... argv) {
    System.out.println(Foo.instance.x);
  }
}

这段代码会打印什么?尝试一下,你会看到它打印"6".这里有一些工作,一个是静态初始化的顺序.执行代码就好像它是这样编写的:

public class Foo {
  private static Foo instance;
  private static final int DELTA = 6;
  private static int BASE;
  static {
    instance = null;
    BASE = 0;
    instance = new Foo(); /* BASE is 0 when instance.x is computed. */
    BASE = 7;
  }
  private int x;
  private Foo() {
    x = BASE + 6; /* "6" is inlined, because it's a constant. */
  }
}


krosenvold.. 5

通常没有"静态"记忆这样的东西.大多数vm都有堆的永久生成(其中类被加载),这通常不是垃圾回收.

静态对象的分配方式与任何其他对象一样.但是,如果它们存活很长时间,它们将在垃圾收集器中的不同代之间移动.但它们不会最终进入permgenspace.

如果您的类永久保留此对象,则只有在vm退出时才会释放它.



1> erickson..:

导入与编译代码中的任何指令都不相关.它们仅在编译时建立别名.

有一些反射方法允许加载类但尚未初始化,但在大多数情况下,您可以假设每当引用类时,它都已初始化.

执行静态成员初始值设定项和静态块,就好像它们都是源代码顺序中的一个静态初始化程序块一样.

在卸载类之前,强引用通过静态成员变量引用的对象.正常ClassLoader从不卸载类,但应用程序服务器使用的类在正确的条件下执行.然而,这是一个棘手的领域,并且是许多难以诊断的内存泄漏的来源 - 这是不使用全局变量的另一个原因.


作为(切向)奖金,这是一个棘手的问题:

public class Foo {
  private static Foo instance = new Foo();
  private static final int DELTA = 6;
  private static int BASE = 7;
  private int x;
  private Foo() {
    x = BASE + DELTA;
  }
  public static void main(String... argv) {
    System.out.println(Foo.instance.x);
  }
}

这段代码会打印什么?尝试一下,你会看到它打印"6".这里有一些工作,一个是静态初始化的顺序.执行代码就好像它是这样编写的:

public class Foo {
  private static Foo instance;
  private static final int DELTA = 6;
  private static int BASE;
  static {
    instance = null;
    BASE = 0;
    instance = new Foo(); /* BASE is 0 when instance.x is computed. */
    BASE = 7;
  }
  private int x;
  private Foo() {
    x = BASE + 6; /* "6" is inlined, because it's a constant. */
  }
}



2> krosenvold..:

通常没有"静态"记忆这样的东西.大多数vm都有堆的永久生成(其中类被加载),这通常不是垃圾回收.

静态对象的分配方式与任何其他对象一样.但是,如果它们存活很长时间,它们将在垃圾收集器中的不同代之间移动.但它们不会最终进入permgenspace.

如果您的类永久保留此对象,则只有在vm退出时才会释放它.

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有