在Java中从复杂对象中释放内存

在Java中从复杂对象中释放内存,java,memory-management,memory-leaks,jaxb,Java,Memory Management,Memory Leaks,Jaxb,我尽力解释我的问题。也许有点抽象 我阅读了一些关于在Java代码中不显式调用GC、finalize方法、指向null等方面的文献 我有一些大的XMLs文件(客户发票)。使用Jaxb,文件在一个复杂的Java对象中封送。其属性是基本类型(Integer、BigDecimal、String等),但也包括其他复杂类的类、其他类的列表、以列表为属性的类的列表等 当我处理对象时,我需要将其从内存中删除。一些XML非常大,我可以避免内存泄漏或OutOfMemoryError情况 因此,我的问题是: 将大对

我尽力解释我的问题。也许有点抽象

我阅读了一些关于在Java代码中不显式调用GC、finalize方法、指向null等方面的文献

我有一些大的XMLs文件(客户发票)。使用Jaxb,文件在一个复杂的Java对象中封送。其属性是基本类型(Integer、BigDecimal、String等),但也包括其他复杂类的类、其他类的列表、以列表为属性的类的列表等

当我处理对象时,我需要将其从内存中删除。一些XML非常大,我可以避免内存泄漏或OutOfMemoryError情况

因此,我的问题是:

  • 将大对象分配给null是否足够?我读到,如果有软引用,GC将不会释放该对象
  • 我是否应该深入清除对象、清除所有列表、为属性分配null等
  • 那么JaxB(我使用的是Java6,所以JaxB是内置的)和软引用呢?JaxB比旧的JibX marshaller更快,但我不知道它在内存使用方面是否更差
  • 我应该用WeakReference或类似的东西来包装megacomplex JaxB类吗
请原谅我混合使用Java内存使用概念、JaxB等。我正在研究大型运行进程的稳定性,以及.hprof文件证明所有发票的所有客户数据都保留在内存中。 请问这是一个简单的、基本的还是罕见的问题


提前感谢

除非有其他东西指向大对象(图)的部分,否则分配大对象引用
null
就足够了

不过,最安全的方法是在应用程序运行一段时间后使用探查器,查看对象引用,看看是否有未正确GC’ed的内容。

hprof files evidence that all customers data of all invoices remains in memory. 
你应该用计算机来分析它。一些好的笔记

将大对象分配给null是否足够?我读到,如果有软引用,GC将不会释放该对象

简而言之,答案是肯定的。将一个大对象(所有的强引用)赋值为null就足够了——如果这样做,垃圾收集器将不再认为该对象是“强可访问的”

在您的情况下,软引用不会成为问题,因为它保证在抛出
OutOfMemoryError
之前,软访问对象将被垃圾收集。它们可能会阻止垃圾收集器立即收集对象(如果不这样做,它们的行为将与弱引用完全相同)。但这种内存使用将是“临时的”,因为如果需要满足分配请求,它将被释放

我是否应该深入清除对象、清除所有列表、为属性分配null等

那可能是个坏主意。如果字段值仅由外部大对象引用,则在收集大对象时,它们也将被垃圾收集。如果他们没有,那么引用他们的代码的其他部分将不会高兴地看到您正在从他们正在使用的列表中删除成员

在最好的情况下,这不起任何作用,在最坏的情况下,这将破坏您的程序。不要让这种诱惑分散了你的注意力,使你无法解决唯一的实际问题,即你的对象是否是强可及的

那么JaxB(我使用的是Java6,所以JaxB是内置的)和软引用呢?JaxB比旧的JibX marshaller更快,但我不知道它在内存使用方面是否更差

我对这些库的相对时间和空间性能不是特别熟悉。但总的来说,对核心库采取非常强烈的“在证明有罪之前无罪”的态度是安全的。如果有一个内存泄漏错误,它可能已经被发现,报告和修复了(除非你正在做一些非常小的事情)

如果有内存泄漏,我99.9%肯定是你自己的代码出了问题

我应该用WeakReference或类似的东西来包装megacomplex JaxB类吗

这听起来像是您在没有考虑实际需要什么的情况下,对问题进行了GC“修复”

如果JaxB类应该被弱引用,那么无论如何这是一个好主意(应该已经存在了)。但如果不应该,那么绝对不要这样做。弱引用更多的是一个整体语义的问题,不应该是为了避免内存问题而专门引入的

如果外部代码需要对对象的引用,那么它就需要一个引用——要让intance被垃圾收集,但仍然可用,这是不可能的。如果它不需要引用(超出某一点),那么它根本不需要引用——最好是取消一个标准[强]引用,或者让它超出范围。弱引用是一种特殊情况,通常在无法完全控制对象不再相关的点时使用。这里可能不是这样

.hprof文件证明所有发票的所有客户数据都保留在内存中

这表明它们确实被引用的时间比需要的时间长

好消息是hprof文件将包含引用它们的确切内容的详细信息。查看您希望已进行GCed的发票实例,并查看是什么引用了它并阻止它进行GCed。然后查看有问题的类,看看您希望如何释放该引用,以及为什么在本例中没有释放该引用


所有良好的性能/内存调整都基于测量。获取堆转储并检查实例和对它们的引用是您的衡量标准。这样做并根据结果采取行动,而不是试图用WeakReferences包装东西,希望它能有所帮助。

代码是否可以引用Jaxb在y之后生成的对象