Describe the bug
When reading histograms from a TFile in a loop memory is not released.
Expected behaviour
In Python I expect when an object goes out of scope, its reference counter decreases and when reaching zero is marker to be deleted, releasing the memory.
I expect very few memory to be used by the script.
I also expect all the memory to be free when the file is closed.
To Reproduce
This script is very similar to the tutorial: ROOT: tutorials/pyroot/pyroot005_tfile_context_manager.py File Reference
import resource
import ROOT
def print_memory_usage(message):
print(f"{message:50} {resource.getrusage(resource.RUSAGE_SELF).ru_maxrss}")
print_memory_usage("start")
histogram_names = open("histogram_names.txt").read().splitlines()
print_memory_usage("read histogram names")
fn = "NTUP_PHYSVAL.40023485._000001.pool.root.1"
with ROOT.TFile.Open(fn) as f:
print_memory_usage("open ROOT file")
for i, histogram_name in enumerate(sorted(histogram_names)):
h = f[histogram_name]
h.SetDirectory(0) # doing nothing
if i % 1000 == 0:
print_memory_usage(f"read {i+1} histograms")
print_memory_usage("read all histograms")
print_memory_usage("outside context maneger (closing ROOT file)")
The ROOT file (60MB) can be downloaded from CERNBox
The txt file is attached
histogram_names.txt (1.4 MB)
The output I get
start 537736
read histogram names 541668
open ROOT file 556796
read 1 histograms 559996
read 1001 histograms 562300
read 2001 histograms 887816
read 3001 histograms 1049608
read 4001 histograms 1534472
read 5001 histograms 1607304
read 6001 histograms 1625864
read 7001 histograms 1639048
read 8001 histograms 1654408
read 9001 histograms 1666312
read 10001 histograms 1682312
read 11001 histograms 1699208
read 12001 histograms 1711368
read 13001 histograms 1726728
read 14001 histograms 1739528
read 15001 histograms 2191056
read 16001 histograms 2258512
read all histograms 2260048
outside context maneger (closing ROOT file) 2260048
- Adding
h.SetDirecotory(0)
(already in the script) is not helping. - Adding
ROOT.TH1.AddDirectory(False)
is not helping. - Adding
gc.collect()
is not helping - Adding
h.Delete()
is solving the issue, but I don’t see why it is needed.
Setup
ROOT v6.32.02
Built for linuxx8664gcc on Jul 08 2024, 09:53:51
From heads/master@tags/v6-32-02
With
Binary directory: /home/turra/micromamba/envs/mamba-python3.11/bin
python: 3.11.8