Skip to content

Address memory leak in imwrite_to_memory()#26

Merged
claydugo merged 2 commits intoramonaoptics:mainfrom
claydugo:fixup_memory_leak
Jan 23, 2026
Merged

Address memory leak in imwrite_to_memory()#26
claydugo merged 2 commits intoramonaoptics:mainfrom
claydugo:fixup_memory_leak

Conversation

@claydugo
Copy link
Member

imwrite_to_memory() leaks memory proportional to image size. Each call retains ~15 MB for a 3072×3072 image, leading to multi-gigabyte memory usage when encoding many images.

Minimal Reproducer

import gc
import numpy as np
import psutil
import ojph

def get_mem_mb():
    return psutil.Process().memory_info().rss / (1024**2)

initial = get_mem_mb()
buffers = []

for i in range(50):
    data = np.random.randint(0, 255, (2048, 2048), dtype='uint8')
    buffers.append(ojph.imwrite_to_memory(data, channel_order='HW'))

    if (i + 1) % 10 == 0:
        gc.collect()
        compressed_mb = sum(len(b) for b in buffers) / (1024**2)
        leaked = get_mem_mb() - initial - compressed_mb
        print(f"After {i+1} images: leaked={leaked:.0f} MB")

gc.collect()
compressed_mb = sum(len(b) for b in buffers) / (1024**2)
leaked = get_mem_mb() - initial - compressed_mb
print(f"\nTotal: compressed={compressed_mb:.0f} MB, leaked={leaked:.0f} MB")
print(f"Leak per image: {leaked/50:.1f} MB")

Expected output (before fix):

After 10 images: leaked=68 MB
After 20 images: leaked=154 MB
After 30 images: leaked=240 MB
After 40 images: leaked=325 MB
After 50 images: leaked=411 MB

Total: compressed=227 MB, leaked=411 MB
Leak per image: 8.2 MB

Expected output (after fix):

After 10 images: leaked=12 MB
After 20 images: leaked=12 MB
After 30 images: leaked=12 MB
After 40 images: leaked=12 MB
After 50 images: leaked=12 MB

Total: compressed=227 MB, leaked=12 MB
Leak per image: 0.2 MB

@claydugo claydugo merged commit fb3abfa into ramonaoptics:main Jan 23, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant