为什么垃圾收集器在未达到最大堆限制的情况下运行?

Why does the Garbage Collector runs without reaching max heap limit?

我正在开发一个用于实时目的的应用程序。为了解决非线性优化问题,我集成了 Java 求解器 jcobyla (https://github.com/cureos/jcobyla)。每次求解器运行时,垃圾收集器都会做大量工作,运行时间很长:

02-09 12:58:16.822: V/onCreate(7061): maxMemory:512524288k

02-09 13:04:23.127: D/dalvikvm(7061): GC_FOR_ALLOC freed 10314K, 40% free 17304K/28544K, paused 16ms, total 16ms   

02-09 13:04:23.177: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 11ms, total 11ms

02-09 13:04:23.222: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 10ms, total 10ms

02-09 13:04:23.322: D/dalvikvm(7061): GC_FOR_ALLOC freed 10304K, 33% free 17303K/25452K, paused 18ms, total 18ms

>02-09 13:04:23.367: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 33% free 17303K/25452K, paused 11ms, total 11ms

02-09 13:04:23.417: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 33% free 17303K/25452K, paused 12ms, total 12ms

02-09 13:04:23.522: D/dalvikvm(7061): GC_FOR_ALLOC freed 10304K, 40% free 17304K/28540K, paused 16ms, total 17ms

02-09 13:04:23.567: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 11ms, total 11ms

02-09 13:04:23.612: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 11ms, total 11ms 

我尝试了很多方法来防止 GC 运行。相信求解器达到了我使用的应用程序的最大堆限制 android:largeHeap="true"。 运行 单独进程中的求解器也没有修复它。

正如您在上面的 LogTag 中看到的,应用程序的最大堆限制约为 512MB,这对于 jcobyla 来说绰绰有余(需要大约 300MB)。 GC 在 运行 之后告诉我有 34% 的空闲空间为 24.85 MB。 运行 jcobyla 时应用程序的总 RAM 使用量约为 20 MB。

为什么 GC 显示的限制与应用程序的最大堆限制不同?

如何增加求解器可能使用的内存?

如何防止 GC 运行?

Every time the solver runs the Garbage Collector is doing a lot of work with a significant runtime

GC_FOR_ALLOC 意味着如果没有一轮 GC 并且可能会扩展堆,您分配内存的请求将无法完成。

wich is more than enough for jcobyla (needs about 300MB)

我不知道你是如何确定的,尤其是 Android。此外,您自己的分析声称情况并非如此,否则您的堆会增长到至少 300MB,但它并没有增长。

Why does the limit GC shows differ from the max heap limit of the app?

因为堆还没有增长到极限。 objective 是为了最小化进程的系统 RAM 占用空间。进程越大,Android 就必须终止其他进程以使所有内容都适合系统 RAM。这会损害用户体验,例如多任务处理。

How to increase the possible memory usage for the solver?

根据您的分析,您不需要增加求解器可能使用的内存。

How can I prevent GC from running?

停止使用利用 GC 的编程语言,或停止为 Android 编程并切换到某些桌面 OS。

您的应用程序是 Android 的众多应用程序之一,也是任何给定 Android 设备上的众多应用程序之一。 Android 设备的系统 RAM 可能很少 -- Android 例如,一个设备可能只有 512MB 的 RAM。这适用于 OS 和所有 运行 应用进程,而不仅仅是你。 Android,尤其是 Dalvik/ART,是围绕协作模型构建的,其中每个进程都试图最小化其内存消耗。

但是:

  • 如果您使用 NDK 在 C/C++ 中编写您的应用程序,不仅没有 GC,而且没有堆限制,除了用户认为的净效应您的应用因其使用的系统 RAM 量而对其设备造成危害

  • 如果您为另一个 OS 编写应用程序,您将受制于 OS 的内存管理策略,而桌面 OS更有可能允许您更积极地使用系统 RAM