内存泄漏使用自动装箱

时间:2017-05-17 12:43:15

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

我关注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对象的强引用,那么它是如何导致内存泄漏的?

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

3 个答案:

答案 0 :(得分:8)

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

您展示的代码以非常高的速率创建对象;他们受垃圾收集立即。其中没有一个&#34; temp&#34;物体以某种方式被遗忘;他们都有资格收藏; GC会在某个时候收集它们。

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

鉴于评论有关&#34;缓存&#34;使用地图的示例:

  • 只要有一个(强大的!)引用来自另一个对象的地图对象,那就是&#34; alive&#34;在GC术语中,该地图是&#34; alive&#34;。因此:该地图中存储的所有对象都是活着的(不适用于GC)
  • 当对该地图的最后一次引用消失时,地图本身就有资格使用该地图。对于地图中的值也是如此 - 除非有一些其他引用此类仍然存活的值。

答案 1 :(得分:3)

从您提供的链接中引用:

  

你能发现内存泄漏吗?

     

我犯了一个错误。我拿了Long(包装类),这是内存泄漏的原因,而不是将原语长为总和。由于自动装箱,sum = sum + l;在每次迭代中创建一个新对象,因此将创建1000个不必要的对象。请避免在原始类和包装类之间混合和匹配。尽可能多地使用原语。

实际上,这里没有内存泄漏。更好的说,它会产生一些冗余的内存使用和垃圾收集。

如果您想模拟真实的内存泄漏,请参阅以下问题:Creating a memory leak with Java

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

如果你看一下内存图,你会发现从GC循环到循环的内存使用情况非常稳定。

例如:

enter image description here

答案 2 :(得分:1)

  

你能发现内存泄漏吗?

     

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

教程中的这个引用是错误的。在这个例子中,你将没有内存泄漏但只是没有高效的内存使用。