【问题标题】:Memory leak using autoboxing使用自动装箱的内存泄漏
【发布时间】:2017-10-16 22:30:30
【问题描述】:

我关注tutorial,下面是自动装箱内存泄漏的示例。

package com.example.memoryleak;
public class Adder {
  public long addIncremental(long l) {
    Long sum=0L;
    sum =sum+l;
    return sum;
  }
  public static void main(String[] args) {
    Adder adder = new Adder();
    for(long ;i<1000;i++)  {
      adder.addIncremental(i);
      }
    }
 }

现在,我可以理解由于自动装箱会创建不必要的对象,但它是如何导致内存泄漏的,我理解的方式是当您持有对死对象的强引用时会导致内存泄漏。现在,在这种情况下,一旦我退出 FOR 循环,就没有对那些 Long 对象的强引用,那么它是如何导致内存泄漏的呢?

请注意,我想了解它是如何导致内存泄漏的,我知道这些对象是不必要的。

【问题讨论】:

  • 您是如何发现内存泄漏的?
  • 教程似乎是绝对垃圾。 DZone 通常那么不好。这是玫瑰印度的品质。
  • @Kayaman 对我来说,这篇文章应该被重写甚至删除。很多错别字,错误的解释。在 cmets 中提供了有用的 cmets,但作者说一切都很好:)
  • 虽然那里没有内存泄漏,但这并不意味着在紧密循环中分配太多对象不可能导致运行时问题。只是你的问题会有所不同。

标签: java memory memory-management memory-leaks garbage-collection


【解决方案1】:

其他答案是正确的:这不是内存泄漏。

您展示的代码以非常高的速度创建对象;并且它们会立即进行垃圾回收。这些“临时”对象都没有被遗忘。他们都有资格领取; GC 会在某个时候收集它们。

内存泄漏是指已用内存不断增加的情况 - 对象没有资格进行垃圾回收。

鉴于评论询问使用地图的“缓存”示例:

  • 只要从另一个在 GC 术语中“活动”的对象对映射对象的单个(强!)引用,该映射就是“活动的”。因此:该地图中存储的所有对象都是活动的(不符合 GC 条件)
  • 当对该映射的最后一个引用消失时,映射本身就符合 GC 的条件。地图中的值也是如此 - 除非有一些 other 引用了这样一个仍然存在的值。

【讨论】:

  • 非常感谢您抽出宝贵的时间来回答,请您看看他们的“示例 2:使用缓存”示例,因为这篇文章让我感到困惑,我的理解是假设有人明确创建Cache 的对象,现在只要创建Cache 的对象的那个类的方法完成,缓存对象就会有资格进行GC,对吧? (2.)假设在该映射中,如果我从我的方法中插入我自己的对象,现在只要缓存对象将被 GC'ed,这些对象将没有任何强引用,因此它们将有资格进行 GC,对?
  • 查看我的更新。但请避免返回更多问题。这个网站不是免费的“我们从一些不太好的教程中理解”服务。当然,在这里或那里点赞总是有助于激励人们;-)
【解决方案2】:

引用您提供的链接:

你能发现内存泄漏吗?

这里我犯了一个错误。我没有采用原始的 long 作为总和,而是采用了 Long(包装类),这是内存泄漏的原因。由于自动装箱,sum=sum+l;每次迭代都会创建一个新对象,因此将创建 1000 个不必要的对象。请避免原始类和包装类之间的混合和匹配。尽量使用原语。

其实这里没有内存泄漏。更好的说法是,它会产生一些多余的内存使用和垃圾回收。

如果你想模拟真实的内存泄漏,请参考这个问题:Creating a memory leak with Java

此外,由于 adder.addIncremental(i); 被忽略,可能会对此代码进行一些 JVM 优化。

如果您查看内存图,您会发现内存使用在 GC 周期之间非常稳定。

例如:

【讨论】:

  • 感谢您的回答。同一个例子中的“示例 2:使用缓存”怎么样,同样的情况下没有真正的内存泄漏,对吧?
  • @pjj,好吧,示例 1 的解释绝对不正确。第二个例子非常依赖逻辑。唯一有用的短语是关于 WeakHashMap。
【解决方案3】:

你能发现内存泄漏吗?

这里我犯了一个错误。而不是把原始的 long 当作 总而言之,我拿了Long(包装类),这是内存的原因 泄漏。由于自动装箱,sum=sum+l;在每个中创建一个新对象 迭代,因此将创建 1000 个不必要的对象。

教程中的这个引用是错误的。在此示例中,您不会有内存泄漏,只是内存使用效率不高。

【讨论】:

    猜你喜欢
    • 2021-09-02
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2012-01-18
    • 2016-01-16
    • 2023-04-10
    相关资源
    最近更新 更多