13

我开始使用 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()))

运行一段时间后,我收到此错误消息:

4

2 回答 2

10

我最近遇到了一个类似的问题,发现如果你经常放置大对象(使用ray.put()),你需要:

  1. 手动调整 python 垃圾收集器使用的阈值

  2. gc.collect()定期致电。

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

问题是默认阈值基于对象的数量,但如果您放置大对象,则 gc 可能永远不会被调用,直到内存不足。我的实用方法如下:

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() 推送大对象并耗尽内存时,调用它可以解决问题。

于 2020-02-15T15:53:34.257 回答
5

快速解决方法是使用:

    ray.shutdown()

我在 Spyder 中编码,它在右下角显示使用的内存百分比。当我多次运行同一个脚本时,我注意到内存百分比值以 3% 的增量增加(基于我拥有的 8 gigs RAM)。这让我想知道,由于增量(每个都对应一个会话),ray 是否正在存储类似会话的东西。

事实证明确实如此。

ray.shutdown()结束会话。ray.init()但是,如果您想再次运行脚本,则需要再次调用。此外,请确保将其放置在正确的位置,以免在仍然需要时结束光线。

这解决了多次运行脚本会增加内存使用的问题。

我不太了解雷,但ray.init()对各种地址有各种争论。我确信必须有一种方法可以通过这些参数之一使 ray 在同一会话上运行。这是猜测。我还没有尝试过任何这些。也许你能弄清楚这一点?

于 2019-09-07T16:09:09.680 回答