所以我有了一个想法:我可以监视这些任务的内存使用情况并暂停(kill -SIGSTOP)或者休眠(使用像CryoPID这样的工具)任务,这些任务会占用太多内存以便以后重新启动它们.通过内存使用,我的意思是“活动虚拟页面”的数量,或实际已被触摸的已分配,非共享内存页面的数量(这些任务可以在不使用它们的情况下分配内存).
我开始寻找一些工具来做到这一点.我知道我可以在内存限制的cgroup中限制或运行任务,但是 – 如果我理解正确 – 这些解决方案将终止进程而不是暂停它.我想避免杀死它们,因为我需要稍后从头开始它们,这意味着浪费时间.而且,它们实际上无法测量活动虚拟页面的数量.
我可以使用真正的虚拟机,但在这种情况下它们似乎有很大的开销 – 具有单独的内核,内存分配等会减少可用内存;我必须跑8个.另外,据我所知,他们也会增加计算开销.
我想,实现这种行为的工具会将一些函数连接到页面错误通知,该通知将决定每个页面错误是否是暂停进程的时间.但我不知道任何工具也会以这种方式工作.
还有其他选择吗?
解决方法
实际上很难很好地实现这一点,因为在一段固定的时间内不可用后,某些共享的资源会过时(请考虑TCP,尽管这也可能适用于使用挂钟的应用程序,或者某些共享内存)在进程脱机期间改变状态).
至于当它达到一定的内存利用率时停止进程,我能想到的黑客攻击会做到这一点.
>您创建一个包含冷冻和内存子系统的cgroup.
>将您的任务放在cgroup内.
>将进程附加到cgroup.event_control并设置一个您不想超过的内存阈值(这在kernel documentation中有所解释).
>超过时间冻结cgroup.内核最终应该逐出这些页面进行交换(提供你的cgroup就足够了).
请注意,“冻结”cgroup不会将页面逐出到媒体持久位置,但是当有足够的时间过去时,它会将页面交换出来,而其他页面需要页面.
即使这确实有效(如果它确实很糟糕),你需要考虑这是否真的可以解决你的问题.
>你怎么知道让一个使用大量内存的进程快速完成其内存密集期并放弃内存不是更好?
>如果你试图通过循环过程公平地唤醒进程 – 你可能会认为你的工作比cpu调度程序已经为你做的更糟糕.
>如果某些进程比其他进程更重要(并且应该被唤醒更长/更快完成),那么分配它们可能比保持其他进程完全冻结更多的cpu时间更好.
>虽然它会很慢 – 您可以添加大量交换(因此您永远不会过度使用)然后大大减少调度程序的交互性,以尝试帮助您减少侵略性页面驱逐.这是在sched_min_granularity_ns中完成的.
不幸的是,最好的解决方案是检查您的任务的能力.遗憾的是,大多数实施方案还不够具体.
或者,您可以等待几年,以便在内核中提供正确的检查点/恢复!