java中的静态内存怎么了? [英] Whats up with static memory in java?

查看:18
本文介绍了java中的静态内存怎么了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This question is for the java language in particular. I understand that there is a static protion of memory set aside for all static code.

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

My question is how is this static memory filled? Is a static object put into static memory at import, or at first reference? Also, do the same garbage collection rules apply to static objects as they do for all other objects?


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();
    }
}

推荐答案

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

Imports don't correlate with any instructions in compiled code. They establish aliases for use at compile time only.

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

There are some reflective methods that allow the class to be loaded but not yet initialized, but in most cases, you can assume that whenever a class is referenced, it has been initialized.

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

Static member initializers and static blocks are executed as if they were all one static initializer block in source code order.

通过静态成员变量引用的对象会被强引用,直到类被卸载.一个普通的 ClassLoader 永远不会卸载一个类,但那些被应用服务器使用的在正确的条件下会这样做.然而,这是一个棘手的领域,并且已经成为许多难以诊断的内存泄漏的根源——这也是不使用全局变量的另一个原因.

An object referenced through a static member variable is strongly referenced until the class is unloaded. A normal ClassLoader never unloads a class, but those used by application servers do under the right conditions. However, it's a tricky area and has been the source of many hard-to-diagnose memory leaks—yet another reason not to use global variables.

作为(切向)奖励,这里有一个棘手的问题需要考虑:

As a (tangential) bonus, here's a tricky question to consider:

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".这里有几件事在起作用,一是静态初始化的顺序.代码的执行就像是这样写的:

What will this code print? Try it, and you'll see that it prints "6". There are a few things at work here, and one is the order of static initialization. The code is executed as if it were written like this:

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. */
  }
}

这篇关于java中的静态内存怎么了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆