-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory not being freed with Image.fromarray #8549
Comments
Does anything change if you add import gc
gc.collect() after |
|
@Yay295, calling the garbage collector explicitly does not make any difference. @radarhere according to the documentation: "There is now a memory pool to contain a supply of recently freed blocks, which can then be reused without going back to the OS for a fresh allocation. This caching of free blocks is currently disabled by default (...)" (https://pillow.readthedocs.io/en/stable/reference/block_allocator.html) It appears that the caching of free blocks should be disabled by default, and tweaking with the PILLOW_BLOCKS_MAX as mentioned in the issue that you reference does not make any difference. |
I see, "caching of free blocks" refers to Pillow/src/libImaging/Storage.c Lines 315 to 338 in 5bff2f3
By default, the following is used instead. Pillow/src/libImaging/Storage.c Lines 339 to 349 in 5bff2f3
Testing further, I think the issue doesn't occur only when loading the array, but rather when saving. |
If I suggest that calling JpegImagePlugin directly improves the situation, do you agree? from PIL import JpegImagePlugin
with BytesIO() as output, Image.fromarray(random_image) as pillow_image:
pillow_image.encoderinfo = {}
JpegImagePlugin._save(pillow_image, output, "filename") |
Hum, It doesn't seem to make any difference |
Do you agree that saving is the problem? As in, I think this code should be fine. with BytesIO() as output, Image.fromarray(random_image) as pillow_image:
pass |
Hum, I do not think so. If I run this: import time
from io import BytesIO
import numpy as np
from PIL import Image
def open_pillow_image():
random_image = (np.random.rand(720, 1280, 3) * 255).astype(np.uint8)
with BytesIO() as output, Image.fromarray(random_image) as pillow_image:
pass
def main():
print("before")
time.sleep(10)
open_pillow_image()
print("after")
time.sleep(1000)
if __name__ == '__main__':
main() The memory used by the script is larger after opening the image. |
Just to be sure, if you remove Pillow, does the problem go away? import time
from io import BytesIO
import numpy as np
def open_pillow_image():
random_image = (np.random.rand(720, 1280, 3) * 255).astype(np.uint8)
with BytesIO() as output:
pass
def main():
print("before")
time.sleep(10)
open_pillow_image()
print("after")
time.sleep(1000)
if __name__ == '__main__':
main() |
Yes, the problem does not exist without pillow. |
I've run this under massif, starting with the first example. I've also run with 100 loops, commenting out the write and using smaller images, and passing the random value in, not writing the jpeg. Valgrind/massif ascii art to follow.
My suspicion here is that it's actually the code that's being loaded. 5MB is in the realm of the size I'd expect. This is the massif run that from the original code, minus the trailing 1000 second sleep. It has all of the significant allocations in the process, at a few shapshots. |
@jmspereira did that answer your question? |
Closing this issue as no feedback has been received. |
What did you do?
Hey everyone,
I have an application that uses pillow to encode numpy arrays as jpegs, however I am seeing a strange behavior regarding the memory usage of that application.
What did you expect to happen?
All allocated memory be freed.
What actually happened?
There is memory that is not freeded.
What are your OS, Python and Pillow versions?
Code that reproduces the problem:
The text was updated successfully, but these errors were encountered: