I have an unusual Class structure, when I'm thinking may be leading to some GC issues.
我有一个不寻常的类结构,当我想到可能导致一些GC问题。
I have a Class: public class Styles
我有一个类:公共类样式
This contains a: public static class Style implements Serializable
它包含一个:public static class Style实现Serializable
Then I have a: public abstract class StyleDescription extends Style
然后我有一个:公共抽象类StyleDescription扩展Style
Which contains a: public static final class CellStyleDescription extends StyleDescription
其中包含:public static final class CellStyleDescription扩展StyleDescription
So, the class hierarchy of CellStyleDescription is pretty unusual.
因此,CellStyleDescription的类层次结构非常不寻常。
Instances of this Class are created, serialized, then later read back in and processed. I know static classes do not handled differently by the garbage collector, but always at the end of processing, I have millions of these Classes still still in memory. Nothing in my code looks like it could be contributing to the instances not being GC'd, except this Class hierarchy.
创建,序列化此类的实例,然后再读回并处理。我知道垃圾收集器对静态类的处理方式不同,但总是在处理结束时,我仍然有数百万个这些类仍在内存中。除了这个Class层次结构之外,我的代码中没有任何内容看起来可能会导致不是GC的实例。
Has anyone experienced anything similar? Or know of anything to look out for with regard to GC and serialization of static classes?
有没有经历过类似的事情?或者知道关于GC和静态类的序列化需要注意什么?
Cheers, Ro
EDIT:
What I should have pointed out is these classes are created then added to another Object (CellInfo) as member variables .... I can see the instances of this class (which is the only container of CellStyleDescription) being GC'd
我应该指出的是创建这些类然后作为成员变量添加到另一个Object(CellInfo)....我可以看到这个类的实例(这是CellStyleDescription的唯一容器)是GC'd
3 个解决方案
#1
1
The keyword static
applied to a class just means it is the same as any other top-level class, and not a nested class, even though its declaration appears inside another class.
应用于类的关键字static意味着它与任何其他*类相同,而不是嵌套类,即使它的声明出现在另一个类中。
Garbage collection is governed by the lifetime of references to classes. If you create lots of instances and keep references to those instances, then they will not be garbage collected. There is nothing wrong with your class hierarchy. Without any more information it is impossible to provide a more meaningful answer.
垃圾收集由对类的引用的生命周期决定。如果您创建了大量实例并保留对这些实例的引用,那么它们将不会被垃圾回收。您的类层次结构没有任何问题。没有任何更多信息,就不可能提供更有意义的答案。
#2
1
In first place, your hierarchy is not that uncommon. In second place, objects are generally not collected until memory is really needed. You should try filling-up memory with other objects and see if they still are there. If they are then most probably you are not releasing all objects as you think.
首先,您的层次结构并不罕见。第二,在真正需要内存之前,通常不会收集对象。您应该尝试用其他对象填充内存,看看它们是否仍在那里。如果他们很可能你没有像你想象的那样发布所有对象。
You could have an inadvertent object retention problem with the abstract
class. Can you make it static
too?
您可能会在抽象类中出现无意的对象保留问题。你能让它静止吗?
#3
0
So I found out the problem.
所以我发现了问题。
Like I said, the Objects were being Serialized, then later read back in. It turns out that OubjectOutputStream keeps a reference to every single Object that gets written out. Objects are compared using the System.identityHashCode(obj) method, and not the Object Hashcode.
就像我说的那样,对象被序列化,然后再读回来。事实证明,OubjectOutputStream保留了对写出的每个Object的引用。使用System.identityHashCode(obj)方法比较对象,而不是Object Hashcode。
More details are here: https://www.securecoding.cert.org/confluence/display/java/SER10-J.+Avoid+memory+and+resource+leaks+during+serialization
更多细节在这里:https://www.securecoding.cert.org/confluence/display/java/SER10-J.+Avoid+memory+and+resource+leaks+during+serialization
Either way, the solution was to reset the ObjectOutputStream regularly
无论哪种方式,解决方案是定期重置ObjectOutputStream
#1
1
The keyword static
applied to a class just means it is the same as any other top-level class, and not a nested class, even though its declaration appears inside another class.
应用于类的关键字static意味着它与任何其他*类相同,而不是嵌套类,即使它的声明出现在另一个类中。
Garbage collection is governed by the lifetime of references to classes. If you create lots of instances and keep references to those instances, then they will not be garbage collected. There is nothing wrong with your class hierarchy. Without any more information it is impossible to provide a more meaningful answer.
垃圾收集由对类的引用的生命周期决定。如果您创建了大量实例并保留对这些实例的引用,那么它们将不会被垃圾回收。您的类层次结构没有任何问题。没有任何更多信息,就不可能提供更有意义的答案。
#2
1
In first place, your hierarchy is not that uncommon. In second place, objects are generally not collected until memory is really needed. You should try filling-up memory with other objects and see if they still are there. If they are then most probably you are not releasing all objects as you think.
首先,您的层次结构并不罕见。第二,在真正需要内存之前,通常不会收集对象。您应该尝试用其他对象填充内存,看看它们是否仍在那里。如果他们很可能你没有像你想象的那样发布所有对象。
You could have an inadvertent object retention problem with the abstract
class. Can you make it static
too?
您可能会在抽象类中出现无意的对象保留问题。你能让它静止吗?
#3
0
So I found out the problem.
所以我发现了问题。
Like I said, the Objects were being Serialized, then later read back in. It turns out that OubjectOutputStream keeps a reference to every single Object that gets written out. Objects are compared using the System.identityHashCode(obj) method, and not the Object Hashcode.
就像我说的那样,对象被序列化,然后再读回来。事实证明,OubjectOutputStream保留了对写出的每个Object的引用。使用System.identityHashCode(obj)方法比较对象,而不是Object Hashcode。
More details are here: https://www.securecoding.cert.org/confluence/display/java/SER10-J.+Avoid+memory+and+resource+leaks+during+serialization
更多细节在这里:https://www.securecoding.cert.org/confluence/display/java/SER10-J.+Avoid+memory+and+resource+leaks+during+serialization
Either way, the solution was to reset the ObjectOutputStream regularly
无论哪种方式,解决方案是定期重置ObjectOutputStream