如何修复Ray不断增长的内存使用量?

18

我开始使用ray进行分布式机器学习,但是我已经遇到了一些问题。内存使用量不断增长直到程序崩溃。虽然我不断清除列表,但内存仍在泄漏。有任何想法为什么会这样吗?

我的规格: 操作系统和分配情况:Ubuntu 16.04 Ray安装来源:二进制 Ray版本:0.6.5 Python版本:3.6.8

我已经尝试使用实验性队列而不是DataServer类,但问题仍然存在。

import numpy as np
import ray
import time
ray.init(redis_max_memory=100000000)


@ray.remote
class Runner():
    def __init__(self, dataList):
        self.run(dataList)

    def run(self,dataList):
        while True:
            dataList.put.remote(np.ones(10))

@ray.remote
class Optimizer():
    def __init__(self, dataList):
        self.optimize(dataList)

    def optimize(self,dataList):
        while True:
            dataList.pop.remote()

@ray.remote
class DataServer():
    def __init__(self):
        self.dataList= []

    def put(self,data):
        self.dataList.append(data)

    def pop(self):
        if len(self.dataList) !=0:
            return self.dataList.pop()
    def get_size(self):
        return len(self.dataList)


dataServer = DataServer.remote()
runner = Runner.remote(dataServer)
optimizer1 = Optimizer.remote(dataServer)
optimizer2 = Optimizer.remote(dataServer)

while True:
    time.sleep(1)
    print(ray.get(dataServer.get_size.remote()))

运行一段时间后,我收到以下错误信息:


1
我认为您忘记包含错误消息了。另外,您的打印语句输出什么?某些列表的长度是否增长得比清除速度更快?一些问题/评论:1)您能否看到哪个进程正在使用所有内存(例如通过“top”)?2)您还可以尝试ray.init(object_store_memory=10**9)。但是,我怀疑其中一个Python actor正在使用越来越多的内存。建议查看Ray时间轴,以查看其是否符合预期(文档位于https://ray.readthedocs.io/en/latest/user-profiling.html#visualizing-tasks-in-the-ray-timeline)。 - Robert Nishihara
2个回答

16

我最近遇到了一个类似的问题,并发现如果你经常使用 ray.put() 放置大型对象,你需要手动调整Python垃圾回收器使用的阈值或定期调用 gc.collect()

我实现了一种方法,检查了已使用的内存量,然后调用垃圾回收器。

问题在于默认阈值是基于对象数量的,但如果你放置的是大型对象,则垃圾回收可能永远不会被调用,直到你耗尽内存。我的实用程序方法如下:

def auto_garbage_collect(pct=80.0):
    """
    auto_garbage_collection - Call the garbage collection if memory used is greater than 80% of total available memory.
                              This is called to deal with an issue in Ray not freeing up used memory.

        pct - Default value of 80%.  Amount of memory in use that triggers the garbage collection call.
    """
    if psutil.virtual_memory().percent >= pct:
        gc.collect()
    return
调用此函数可解决通过ray.put()推送大对象而导致内存耗尽的问题。

谢谢您提供的示例。我无法编辑此答案,但您需要在某处添加“import gc”和“import psutil”。 - troymyname00

6
一个快速的解决方法是使用:

    ray.shutdown()

我在Spyder编码,其在右下角显示内存使用百分比。当我多次运行相同的脚本时,我注意到内存百分比值按照3%的增量递增(基于我拥有的8GB RAM)。这让我想知道ray是否储存了类似会话的东西,因为增量每个都对应一个会话。
事实证明它确实有。 ray.shutdown()结束会话。但是,如果您想再次运行脚本,则需要再次调用ray.init()。而且,请确保将其放置在正确的位置以便在仍需ray时不要结束ray。
这解决了多次运行脚本导致内存使用量增加的问题。
我不太了解Ray,但ray.init()有各种关于地址的参数。我确定其中必定有一种方法可以通过这些参数之一使ray在同一会话上运行。这只是推测,我还没有尝试过任何操作。也许你可以弄清楚?

2
我想重启你的笔记本电脑也可以解决这个问题 :) 这两种解决方法在质量上没有区别。 - mirekphd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接