在 Java 中使用太多静态变量会导致内存泄漏吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/641462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can using too many static variables cause a memory leak in Java?
提问by harshit
If my application has too many static variables or methods, then as per definition they will be stored in heap. Please correct me if I am wrong
如果我的应用程序有太多静态变量或方法,那么根据定义,它们将存储在堆中。如果我错了,请纠正我
1) Will these variables be on heap until application is closed?
2) Will they be available for GC at any time? If not can I say it is a memory leak?
1) 在应用程序关闭之前,这些变量会在堆上吗?
2) 它们是否可以随时用于 GC?如果不是,我能说这是内存泄漏吗?
采纳答案by Uri
Static methods are just methods, they are not stored on the heap, they just don't get to use a "this" parameter.
静态方法只是方法,它们不存储在堆中,它们只是无法使用“this”参数。
Static variables serve as "roots" to the GC. As a result, unless you explicitly set them to null, they will live as long as the program lives, and so is everything reachable from them.
静态变量充当 GC 的“根”。因此,除非您明确地将它们设置为 null,否则它们将与程序存在的时间一样长,并且可以从它们访问的所有内容也是如此。
A situation is only considered a memory leak if you intend for the memory to become free and it doesn't become free. If you intend for your static variable to contain a reference to an object for part of the time, and you forget to set it to null when you're done with that object, you would likely end up with a leak. However, if you put it in the static variable and intend for it to be there for as long as the program is running, then it is most definitely not a leak, it is more likely a "permanent singleton". If the object got reclaimed while you wanted it to still exist, that would have been very bad.
如果您打算让内存变得空闲并且它不会变得空闲,则这种情况仅被视为内存泄漏。如果您打算让静态变量在一段时间内包含对某个对象的引用,而在处理完该对象后忘记将其设置为 null,则最终可能会发生泄漏。但是,如果您将它放在静态变量中并打算在程序运行期间一直存在,那么它绝对不是泄漏,它更有可能是“永久单例”。如果对象在您希望它仍然存在时被回收,那将是非常糟糕的。
As for your question about the heap: All objects in Java exist either on the heap or on the stack. Objects are created on the heap with the new operator. A reference is then attached to them. If the reference becomes null or falls out of scope (e.g., end of block), the GC realizes that there is no way to reach that object ever again and reclaims it. If your reference is in a static variable, it never falls out of scope but you can still set it to null or to another object.
至于你关于堆的问题:Java中的所有对象都存在于堆上或堆栈上。使用 new 运算符在堆上创建对象。然后将引用附加到它们。如果引用变为空或超出范围(例如,块结束),GC 会意识到无法再次访问该对象并回收它。如果您的引用在静态变量中,它永远不会超出范围,但您仍然可以将其设置为 null 或另一个对象。
回答by hhafez
As long as you can reference these variables from somewhere in the code it can't by GCed which means that they will be there until the end of the application.
只要您可以从代码中的某处引用这些变量,GC 就不能,这意味着它们将一直存在到应用程序结束。
Can you call it a memory leak, I wouldn't call it a memory leak, usually a memory leak is memory that you normally expect to recover but you never do, or you only recover part of it. Also memory leaks usually get worse in time (eg: every time you call a method more memory is "leaked") however in this case the memory usage for those variables is (kind of) static.
你能称之为内存泄漏吗,我不会称它为内存泄漏,通常内存泄漏是你通常希望恢复但你从来没有这样做的内存,或者你只恢复了它的一部分。此外,内存泄漏通常会随着时间的推移变得更糟(例如:每次调用一个方法时,都会“泄漏”更多内存),但是在这种情况下,这些变量的内存使用情况是(某种)静态的。
回答by patros
It won't cause a memory leak in the classic C sense... For example
它不会导致经典 C 意义上的内存泄漏......例如
Class A{
static B foo;
...
static void makeFoo(){
foo = new B();
foo = new B();
}
In this case, a call to makeFoo() won't result in a memory leak, as the first instance can be garbage collected.
在这种情况下,调用 makeFoo() 不会导致内存泄漏,因为第一个实例可以被垃圾收集。
回答by Tom Hawtin - tackline
Objects directly or indirectly referenced by statics will remain on the heap until the appropriate class loader can be collected. There are cases (ThreadLocal, for instance) where other objects indirectly reference the class loader causing it to remain uncollected.
静态直接或间接引用的对象将保留在堆上,直到可以收集适当的类加载器。在某些情况下(例如 ThreadLocal),其他对象间接引用类加载器导致它保持未收集状态。
If you have a static List, say, and add references to it dynamically, then you can very easily end up with "object lifetime contention issues". Avoid mutable statics for many reasons.
例如,如果您有一个静态列表并动态添加对它的引用,那么您很容易以“对象生存期争用问题”告终。出于多种原因避免可变静态。
回答by ReneS
If you have a static hashmap and you add data to it... the data will never disappear and you have a leak - in case you do not need the data anymore. If you need the data, it is not a leak, but a huge pile of memory hanging around.
如果您有一个静态哈希图并向其中添加数据......数据将永远不会消失并且您有泄漏 - 以防您不再需要数据。如果你需要数据,那不是泄漏,而是一大堆内存。