-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Memory leak in models #3179
Description
Not sure if this is a bug or I'm missing something, but I couldn't find any solution in the documentation or after attempting some debugging. Not sure if this has anything to do and could be addressed with the StrongAgentSet change.
Describe the bug
When I run a few instance of a model (encapsulated within a function), objects don't get cleaned and they accumulate in RAM.
Expected behavior
If a model is run within a function, I would expect no trace in memory of the model once the function has been exited.
To Reproduce
Basic model from https://mesa.readthedocs.io/latest/overview.html.
import mesa
class MyAgent(mesa.Agent):
def __init__(self, model, age):
super().__init__(model)
self.age = age
def step(self):
self.age += 1
# print(f"Agent {self.unique_id} now is {self.age} years old")
# Whatever else the agent does when activated
class MyModel(mesa.Model):
def __init__(self, n_agents):
super().__init__()
self.grid = mesa.space.MultiGrid(10, 10, torus=True)
for _ in range(n_agents):
initial_age = self.random.randint(0, 80)
a = MyAgent(self, initial_age)
coords = (self.random.randrange(0, 10), self.random.randrange(0, 10))
self.grid.place_agent(a, coords)
def step(self):
self.agents.shuffle_do("step")
def main():
n_agents=1000
model = MyModel(n_agents=n_agents)
for i in range(20 * n_agents):
model.step()
if __name__ == '__main__':
print(f'Mesa version: {mesa.__version__}')
import objgraph
print(objgraph.show_growth())
main()
print(objgraph.show_growth())
main()
print(objgraph.show_growth())Output:
Mesa version: 3.3.1
function 22515 +22515
dict 11268 +11268
tuple 9130 +9130
cell 4286 +4286
list 4265 +4265
ReferenceType 3169 +3169
wrapper_descriptor 3112 +3112
set 2918 +2918
getset_descriptor 2894 +2894
method_descriptor 2249 +2249
None
ReferenceType 5171 +2002
MyAgent 1000 +1000
list 4378 +113
dict 11273 +5
function 22517 +2
set 2920 +2
method 143 +2
WeakKeyDictionary 6 +2
AgentSet 2 +2
Random 2 +1
None
ReferenceType 7173 +2002
MyAgent 2000 +1000
list 4491 +113
dict 11278 +5
function 22519 +2
set 2922 +2
method 145 +2
WeakKeyDictionary 8 +2
AgentSet 4 +2
Random 3 +1
None
Additional context
Removing agents from the grid space and the model explicitly (with model.remove_all_agents()) does removes the MyAgent objects, but this should also happen automatically. And they don't seem to be enough if the model has a NetworkGrid instead of the MultiGrid.