【发布时间】:2010-10-13 02:11:04
【问题描述】:
如果我的应用程序有太多静态变量或方法,那么根据定义,它们将存储在堆中。如果我错了,请纠正我
1) 在应用程序关闭之前,这些变量会一直在堆上吗?
2) 它们是否随时可用于 GC?如果不是,我能说这是内存泄漏吗?
【问题讨论】:
标签: java memory-management memory-leaks
如果我的应用程序有太多静态变量或方法,那么根据定义,它们将存储在堆中。如果我错了,请纠正我
1) 在应用程序关闭之前,这些变量会一直在堆上吗?
2) 它们是否随时可用于 GC?如果不是,我能说这是内存泄漏吗?
【问题讨论】:
标签: java memory-management memory-leaks
如果您有一个静态哈希图并向其中添加数据...数据将永远不会消失并且您有泄漏 - 以防您不再需要数据。如果你需要数据,那不是泄漏,而是一大堆内存。
【讨论】:
静态方法只是方法,它们不存储在堆中,它们只是不能使用“this”参数。
静态变量充当 GC 的“根”。因此,除非您将它们显式设置为 null,否则它们将与程序存在一样长,因此可以从它们访问的所有内容。
仅当您打算让内存变得空闲并且它没有变得空闲时,才会将这种情况视为内存泄漏。如果您打算让您的静态变量在部分时间内包含对对象的引用,并且在完成该对象时忘记将其设置为 null,那么您最终可能会出现泄漏。但是,如果您将它放在静态变量中并打算在程序运行时一直存在,那么它绝对不是泄漏,它更有可能是“永久单例”。如果该对象在您希望它仍然存在时被回收,那将是非常糟糕的。
关于堆的问题:Java 中的所有对象要么存在于堆上,要么存在于堆栈上。使用 new 运算符在堆上创建对象。然后将参考附加到它们。如果引用变为 null 或超出范围(例如,块结束),GC 会意识到无法再次到达该对象并回收它。如果您的引用在静态变量中,它永远不会超出范围,但您仍然可以将其设置为 null 或另一个对象。
【讨论】:
静态直接或间接引用的对象将保留在堆上,直到可以收集适当的类加载器。在某些情况下(例如 ThreadLocal),其他对象间接引用类加载器导致它保持未被收集。
例如,如果您有一个静态列表并动态添加对它的引用,那么您很容易以“对象生命周期争用问题”告终。出于多种原因,请避免使用可变静态。
【讨论】:
Function、String、Object 和类本身(通过方法引用)。
它不会导致经典 C 意义上的内存泄漏...例如
Class A{
static B foo;
...
static void makeFoo(){
foo = new B();
foo = new B();
}
在这种情况下,调用 makeFoo() 不会导致内存泄漏,因为第一个实例可以被垃圾回收。
【讨论】:
只要您可以从代码中的某处引用这些变量,GCed 就不能,这意味着它们将一直存在,直到应用程序结束。
你能称之为内存泄漏吗,我不会称之为内存泄漏,通常内存泄漏是你通常希望恢复但你从未这样做的内存,或者你只恢复了它的一部分。此外,内存泄漏通常会随着时间的推移变得更糟(例如:每次调用方法时都会“泄漏”更多内存),但是在这种情况下,这些变量的内存使用量是(某种)静态的。
【讨论】: