2

我正在使用 simpy 创建具有大量对象(数百万)的 DES。我遇到了内存问题,并试图弄清楚如何解决这个问题。可以计算出哪些对象将不再与其他进程进行交互,因此理论上我可以从模拟中删除这些对象以释放内存。我创建了以下测试。

import psutil as ps
import simpy
import random


class MemoryUse(object):
    """a class used to output memory usage at various times within the sim"""

    def __init__(self, env, input_dict):

        self.env = env
        self.input_dict = input_dict

        self.env.process(self.before())
        self.env.process(self.during())
        self.env.process(self.after_sr())
        self.env.process(self.after())

    def before(self):

        yield self.env.timeout(0)
        print("full object list and memory events at time: ", self.env.now, " ", ps.virtual_memory())
        print(len(self.input_dict), len(self.env._queue))

    def during(self):
        yield self.env.timeout(2)
        print("full object list and events ar time: ", self.env.now, " ", ps.virtual_memory())
        print(len(self.input_dict), len(self.env._queue))

    def after_sr(self):

        yield self.env.timeout(4)
        print("reduced object list and reduced events at time: ", self.env.now, " ", ps.virtual_memory())
        print(len(self.input_dict), len(self.env._queue))

    def after(self):
        yield self.env.timeout(6)
        print("no objects and no events at time: ", self.env.now, " ", ps.virtual_memory())
        print(len(self.input_dict), len(self.env._queue))


class ExObj(object):
    """a generic object"""

    def __init__(self, env, id, input_dict):

        self.env = env
        self.id = id
        self.input_dict = input_dict

        if random.randint(0, 100) < 70:
            # set as SR
            self.timeout = 2
        else:
            self.timeout = 4

    def action(self):

        yield self.env.timeout(self.timeout)

        del self.input_dict[self.id]


class StartObj(object):
    """this enables me to create the obj events after the sim has started so as to measure memory usage before the events
    associated with the object exists"""

    def __init__(self, env, input_dict):

        self.env = env
        self.input_dict = input_dict

        self.env.process(self.start_obj())

    def start_obj(self):

        yield self.env.timeout(1)

        for k, v in self.input_dict.items():
            self.env.process(v.action())

        yield self.env.timeout(0)

# memory usage before we do anything
print("before all: ", ps.virtual_memory())

# create simpy env
env = simpy.Environment()
obj_dict = {}

# create memory calculation events
memory = MemoryUse(env, obj_dict)

# create objects
for i in range(2500000):
    obj_dict[i] = ExObj(env, i, obj_dict)


# create process that will itself start events associated with the objects
start = StartObj(env, obj_dict)

# run
env.run()

# clear the dict if not already clear
for j in range(2500000):
    obj_dict.clear()

# final memory check
print("after all: ", ps.virtual_memory())
print(len(obj_dict))

我预计到时间 4 内存使用量会下降,因为许多对象已被删除并且进程已完成(大约 70%)。但是内存使用似乎保持不变(见下文)。为什么会这样?什么在使用这个内存?已完成的流程是否保留在模拟中?

before all:  svmem(total=42195423232, available=39684155392, percent=6.0, used=2246373376, free=38884859904, active=2390749184, inactive=441712640, buffers=263155712, cached=801034240, shared=28721152)
full object list and memory events at time:  0   svmem(total=42195423232, available=38834251776, percent=8.0, used=3096276992, free=38035181568, active=3241959424, inactive=441466880, buffers=263159808, cached=800804864, shared=28721152)
2500000 4
full object list and events ar time:  2   svmem(total=42195423232, available=35121584128, percent=16.8, used=6808891392, free=34322219008, active=6947561472, inactive=441761792, buffers=263163904, cached=801148928, shared=28774400)
2500000 2500002
reduced object list and reduced events at time:  4   svmem(total=42195423232, available=35120973824, percent=16.8, used=6809530368, free=34321600512, active=6948368384, inactive=441737216, buffers=263168000, cached=801124352, shared=28745728)
767416 767417
no objects and no events at time:  6   svmem(total=42195423232, available=38448134144, percent=8.9, used=3482365952, free=37648760832, active=3627053056, inactive=441733120, buffers=263172096, cached=801124352, shared=28745728)
0 0
after all:  svmem(total=42195423232, available=38825793536, percent=8.0, used=3104706560, free=38026420224, active=3250180096, inactive=441733120, buffers=263172096, cached=801124352, shared=28745728)
0

Process finished with exit code 0
4

0 回答 0