我尽力解释我的问题。也许这有点抽象。
我读过一些关于不在Java代码中明确调用GC,终结方法,指向null等的文献。
我有一些大型XML文件(客户发票)。使用Jaxb,文件在复杂的Java对象中进行编组。它的属性是基本类型(Integer,BigDecimal,String等),但也包括其他复杂类的类,其他类的列表,列表作为属性的类列表等。
当我用对象做我的东西时,我需要将它从内存中删除。有些XML非常大,我可以避免内存泄漏或OutOfMemoryError情况。
所以,我的问题是:
请原谅我混合Java内存使用概念,JaxB等。我正在研究大型运行流程的稳定性,.hprof文件证明所有客户的所有客户数据仍然存在记忆。 如果这是一个简单,基本或罕见的问题,请原谅。
提前致谢
答案 0 :(得分:9)
除非其他东西指向大对象(图形)的某些部分,否则分配大对象引用null
就足够了。
最安全的是,在应用程序运行一段时间后使用分析器,查看对象引用,看看是否存在未正确GC的东西。
答案 1 :(得分:4)
将大对象分配给null是否足够?我读过,如果有软引用,GC就不会释放对象。
简短的回答是是。将一个大对象(所有强引用)分配给null就足够了 - 如果这样做,垃圾收集器将不再将该对象视为“强烈可访问”。
在您的情况下,软引用不会成为问题,因为它可以保证在引发OutOfMemoryError
之前将软件可访问的对象进行垃圾回收。它们可能会阻止垃圾收集器立即收集对象(如果它们没有,它们的行为与弱引用完全相同)。但是这种内存使用将是“临时的”,因为如果需要它来满足分配请求,它将被释放。
我应该深入清除对象,清除所有列表,为属性分配null等吗?
这可能是一个坏主意。如果字段值仅由外部大对象引用,则在收集大对象时它们也将被垃圾收集。如果它们不是,那么引用它们的代码的其他部分将不会高兴地看到您正在从他们正在使用的列表中删除成员!
在最好的情况下,这没有任何作用,在最坏的情况下,这会破坏你的程序。不要让这种诱惑分散您的注意力,以解决您的物体是否可以强烈接触的唯一实际问题。
JaxB(我使用的是Java6,内置JaxB)和软引用怎么样? JaxB比旧的JibX marshaller更快,但我不知道它在内存使用方面是否更糟。
我对这些库的相对时间和空间性能并不是特别熟悉。但总的来说,可以安全地假设一个非常强大的“天真无邪,直到被证明有罪”的态度与核心库。如果存在内存泄漏错误,那么现在可能已经找到,报告并修复了(除非你正在做一些非常利基)。
如果内存泄漏,我99.9%确定这是你自己的错误代码。
我应该用WeakReference或类似的东西包装megacomplex JaxB类吗?
听起来你可能会在不考虑实际需要的情况下对问题进行GC“修复”。
如果JaxB类应该被弱引用,那么无论如何这都是一个好主意(它应该已经存在)。但如果不应该,那么绝对不要这样做。弱引用更多地是整体语义的问题,并且不应该是您专门为避免内存问题而引入的内容。
如果外部代码需要对对象的引用,那么它需要一个引用 - 没有什么魔法可以让intance被垃圾收集但仍然可用。如果它不需要引用(超过某一点),那么它根本不需要一个 - 更好地使标准[强]引用无效,或者让它超出范围。弱参考是一种专业情况,通常在您无法完全控制对象不再相关的点时使用。哪个可能不是这里的情况。
<。> .hprof文件证明所有发票的所有客户数据都保留在内存中。
这表明他们确实被引用的时间超过了必要时间。
好消息是hprof文件将包含确切引用它们的详细信息。查看您希望已经过GCed的发票实例,并查看引用它的内容并防止它被GCed。然后查看有问题的类,看看你希望如何释放该引用,以及为什么它不在这种情况下。
所有良好的性能/内存调整都基于测量。进行堆转储,检查实例和对它们的引用是您的测量。这样做并对结果采取行动,而不是试图在WeakReferences中包装它,希望它可能有所帮助。
答案 2 :(得分:3)
你写了
hprof files evidence that all customers data of all invoices remains in memory.
您应该使用mat进行分析。 http://memoryanalyzer.blogspot.in/
处的一些好注意事项