Deleted dotnet object does not get garbage collected

Environment

  • Pythonnet version: 3.0.0rc3
  • Python version: 3.10.5
  • Operating System: Windows 10 20H2
  • .NET Runtime: 6.0.6

Details

  • Describe what you were trying to get done.

Create dotnet-object and delete it. If I do that a lot I get memory issues. It seems the never get cleared by the Python- or dotnet-gc. This is not a problem in pythonnet 2.5.2

  • What commands did you run to trigger this issue?
import gc
import clr
import psutil
import matplotlib.pyplot as plt
import System

# Create dict store count of objects left
types = [
    str,
    System.String,
]
types = {obj: 0 for obj in types}

N = 1_000
str_size = 1_000_000

memory_py = [0 for _ in range(N + 2)]
memory_py[0] = psutil.virtual_memory().used
for ii in range(N):
    s_py = str('a' * str_size)
    del s_py
    memory_py[ii + 1] = psutil.virtual_memory().used - memory_py[0]

gc.collect()
# See what types of objects are still present
for obj in gc.get_objects():
    if type(obj) in list(types.keys()):
        types[type(obj)] += 1
print(types)
memory_py[ii + 2] = psutil.virtual_memory().used - memory_py[0]
memory_py[0] = 0
{<class 'str'>: 0, <class 'System.String'>: 0}
memory_net = [0 for _ in range(N + 2)]
memory_net[0] = psutil.virtual_memory().used
s_py = str('a' * str_size)
for ii in range(N):
    s_net = System.String(s_py)
    del s_net
    memory_net[ii + 1] = psutil.virtual_memory().used - memory_net[0]

gc.collect()
# See what types of objects are still present
for obj in gc.get_objects():
    if type(obj) in list(types.keys()):
        types[type(obj)] += 1
print(types)
memory_net[ii + 2] = psutil.virtual_memory().used - memory_net[0]
memory_net[0] = 0
{<class 'str'>: 0, <class 'System.String'>: 1000}

You can also visualize the memory consumption:

fig, ax = plt.subplots()
ax.plot(memory_py, label='Python object')
ax.plot(memory_net, label='DotNet object')
ax.legend()
plt.show(fig)

3 0

You can execute the same code with pythonnet 2.5.2 (Python 3.9.13) and get the following figure

2 5