如果我 运行 以编程方式在循环内使用垃圾收集器。它会影响我的 Android 申请吗?

If I run the Garbage Collector programmatically inside a loop. In does it affect my Android application?

尽量减少内存泄漏问题并优化我的应用程序。我想确保我的应用程序的稳定性,为此我正在研究内存分配和释放的问题。

我在循环中创建了一个数据对象 class 并将其添加到列表中,之后,我不需要该数据 class 对象,所以我想删除该对象在不关闭屏幕或 activity.

的情况下从内存中获取

为此,在将对象添加到列表后,我调用了 System.gc()。

是否因为垃圾回收调用过多而影响应用?

要使您的应用真正具有响应能力,请执行以下操作。

  • 根据需要遵循设计模式原则。
  • 为您的项目创建好的架构。
  • 正确处理位图 - 不使用时不要忘记对位图调用 recycle(),这会导致内存问题。
  • 使用 componentcallback2 我们可以在进行密集处理之前在 service/activity 中获取内存信息。
  • 避免在应用程序中使用 bg 服务。如果必须专注于有效的处理方式或使用 Job Scheduler 或意图 service.The 服务中的缺点是服务使用的 RAM(内存)对另一个进程不可用。
  • 我们可以使用 sparseArray、sparseBooleanArray 代替 hashmap。
  • 不要在 onDraw 方法()中创建局部变量。
  • 删除内存密集型资源和依赖项。
  • 减小 apk 的整体大小。
  • 使用 dagger2 进行依赖注入,它不使用反射 api,但其他库使用反射 api 它们在 运行 应用程序时给出了明显的延迟。
  • 建议使用 xml 文件创建所有布局。最好使用 Coordinator 布局。
  • 在主线程之外完成所有耗时的过程。
  • 当通过网络调用并行加载多个图像时,使用缓存机制。

如果您仍然想手动启动垃圾收集,您可以这样做,但不建议您终止应用并休眠。

垃圾收集器只收集代码中不再引用的对象。通过将其添加到列表中,引用将存储在列表中,只要列表仍被引用,该引用就会保留。如果您希望 GC 收集您的对象,则必须发生以下情况之一(假设该对象和列表都未在其他任何地方被引用):

  • 对象已从列表中删除
  • 列表超出范围
  • 列表变量设置为null

在这种情况下,GC 将收集该对象。一般来说,系统会很聪明地判断何时调用 GC,因此手动调用 GC 会增加程序的复杂性并降低其性能(因为 GC 也需要 CPU 时间),因此不推荐使用。

如果您希望避免内存泄漏:

  • 确保没有对您的对象的过时引用
  • 使用WeakReference

在评论中您问“如果同时调用多个 gc 调用会发生什么情况?

When in doubt, look at the source code.

Source Code of System.gc() method

 /**
 * Runs the garbage collector.
 * <p>
 * Calling the <code>gc</code> method suggests that the Java Virtual
 * Machine expend effort toward recycling unused objects in order to
 * make the memory they currently occupy available for quick reuse.
 * When control returns from the method call, the Java Virtual
 * Machine has made a best effort to reclaim space from all discarded
 * objects.
 * <p>
 * The call <code>System.gc()</code> is effectively equivalent to the
 * call:
 * <blockquote><pre>
 * Runtime.getRuntime().gc()
 * </pre></blockquote>
 *
 * @see     java.lang.Runtime#gc()
 */
public static void gc() {
    boolean shouldRunGC;
    synchronized (LOCK) {
        shouldRunGC = justRanFinalization;
        if (shouldRunGC) {
            justRanFinalization = false;
        } else {
            runGC = true;
        }
    }
    if (shouldRunGC) {
        Runtime.getRuntime().gc();
    }
}

Declaration of justRanFinalization field.

/**
 * If we just ran finalization, we might want to do a GC to free the finalized objects.
 * This lets us do gc/runFinlization/gc sequences but prevents back to back System.gc().
 */
private static boolean justRanFinalization;

因此,如果 justRanFinalizationfalse,那么通过多次调用 gc,您将创建一个 boolean 并不必要地获取一个 LOCK