【问题标题】:Continuous Memory Allocation Not Causing Leakage连续内存分配不会导致泄漏
【发布时间】:2018-04-21 02:58:21
【问题描述】:

我正在尝试在 Android 中模拟 OutOfMemory 异常。我的方法基本上是让静态 ArrayList 不断添加long[2048] 数组。

我让程序运行了一段时间,它收集了 685 个 long[2048] 实例。使用 Android Studio 的 3.0 分析器,堆转储如下所示:

| class name | alloc count | shallow size | retained size |
| ---------- | ----------- | ------------ | ------------- |
| long[]     | 685         | 9997168      | 9997168       |

所以,内存没有被垃圾收集。无论如何,应用程序的堆内存保持在 40Mb 并且不会下降。

为什么会这样?应用程序不应该像现在没有明天一样泄漏内存吗? JVM这次做了什么?

另外,shallow sizeretained size 有什么区别?

PS:代码如下:

    public class MainActivity extends AppCompatActivity {
    static List<long[]> myList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                myList.add(loadStuff());
            }
        });
    }


    static long[] loadStuff() {
        return new long[2048];
    }
}

【问题讨论】:

  • 我不明白这个问题。其实就是内存泄露,为什么说不是呢?
  • 因为 Android Studio 3.0 内存分析器显示应用程序总内存从一开始就保持在 40mb。它有点高,但垃圾收集器启动并将其返回到 40mb。
  • 在您的 onClick 中添加一个循环来执行此操作,例如 100000 次并单击几次 :)
  • 我想这肯定会引发异常,但我的问题是为什么应用程序在“缓慢”泄漏时不抛出异常。
  • 您需要多次点击才能获得OutOfMemory,700 次点击相当于 10mb,具体取决于您的手机,但我敢打赌,您需要的不止这些。这最终会发生,内存没有被垃圾收集。

标签: java android memory memory-management jvm


【解决方案1】:

shallow size 是现在占用的内存,而 reserved size 是收集垃圾后将被释放的大小,请参阅此处的参考

shallow vs retained size

【讨论】:

猜你喜欢
  • 2011-11-09
  • 2012-06-10
  • 2019-08-12
  • 2016-01-17
  • 1970-01-01
  • 2012-08-10
  • 2022-06-13
  • 2020-04-06
  • 1970-01-01
相关资源
最近更新 更多