`TIS.Imaging.ICImagingControl()` is not released properly and cause memory leaks
NatanBagrov opened this issue · comments
Hello,
I reference the issue with this line of code:
When wrapping the referenced file with a for
loop, the memory explodes. I've isolated the relevant line (above).
Apparently, ic.LiveStop()
(line 82) does not release all resources.
Any suggestions? I don't want to keep ic
as some global state.
Best regards!
Hello
ic.LiveStop() stops the live video stream only. But it keeps the used video capture device open, so you can call ic.LiveStart() again.
If you want to release as much as possible resources, you must delete the created ic object instance. I must admit, I am not that Python expert, so I do not know, how to delete that. But I guess, you know that.
I hope, in the for loop you have the trhee lines
snapsink.SnapSingle(TimeSpan.FromSeconds(5))
frame = snapsink.SnapSingle(TimeSpan.FromSeconds(5))
TIS.Imaging.FrameExtensions.SaveAsJpeg( frame,"image.jpg", 75)
only. Putting the complete code into a for loop does not make any sense,
Stefan
Hi Stefan,
The for
loop is just an example. If I have a TCP server, and this function as callback - the function will be called on every request, and I don't want to have ic
as a persistent state.
I cannot just delete ic
using "Python" because it is create via an external library, TIS.Imaging.ICImagingControl35.dll
- so the library should provide some API to manage it, which I guess it does, but the code sample does not use it.
As far as I know,
ic = TIS.Imaging.ICImagingControl()
is the same as
TIS.Imaging.ICImagingControl() ic = new TIS.Imaging.ICImagingControl() ;
in C#
If I put that into a function like
private void image()
{
TIS.Imaging.ICImagingControl ic = new TIS.Imaging.ICImagingControl() ;
}
```The "ic" lives are long as I stay in the function. It is deleted or marked for deletion, when the function is left. The C# garbage collector should sooner or later free the memory. This can be forced by
private void image()
{
TIS.Imaging.ICImagingControl ic = new TIS.Imaging.ICImagingControl() ;
ic.dispose();
gc.collect();
}
I am not sure, whether there is a similar thing in Python. It may also is a good idea, what PythonNet does in this case http://pythonnet.github.io. At the end of the page is some code with "using" That would translate to
with ic = TIS.Imaging.ICImagingControl():
' open device, configre device, get images, close device...
I found that at Stackoverflow: https://stackoverflow.com/questions/1369526/what-is-the-python-keyword-with-used-for
It seems to answer your question regarding the resources and is worth a try,
Stefa
In C# it works because C# has its garbage collector, and this object is a managed resource there. Furthermore, the with
statement does not work because TIS.Imaging.ICImagingControl
(in Python) does not implement __enter__
nor __exit__
.
Any chance to check with the development team how to dispose this object via Python, and release the memory allocated by it?
Did you try the
with ic = TIS.Imaging.ICImagingControl():
' open device, configre device, get images, close device...
python code? (I just see, that my previous answer above is nicely mal-formatted...)
Stefan
Hello
the "with" thingy does not work. But "ic.Dispose()" does the job:
import ctypes as C
import msvcrt as m
# Import PyhtonNet
import clr
# Load IC Imaging Control .NET
clr.AddReference('TIS.Imaging.ICImagingControl35')
# Import the IC Imaging Control namespace.
import TIS.Imaging
print("start")
m.getch()
print("started")
for r in range(100):
ic = TIS.Imaging.ICImagingControl()
ic.Device="DFK Z30GP031"
ic.LiveStart()
ic.LiveStop()
ic.Device = ""
ic.Dispose()
print("done")
m.getch()
I hope, this works for you.
Stefan
Hi Stefan,
Looks like it did the trick. I've added a pull-request as-well.
Hello
Thank you for the pull request. I merged that, but from my point of view, it should not be necessary in the sample, because I would expect the Python garbage collector to clean up memory automatically on program end. However, I can be wrong here, because I am not Python expert.
Stefan
Hello
Thank you for the pull request. I merged that, but from my point of view, it should not be necessary in the sample, because I would expect the Python garbage collector to clean up memory automatically on program end. However, I can be wrong here, because I am not Python expert.
Stefan
You are half correct - this memory will be released, but not by Python's garbage collector, because it is unmanaged resource. It will be released by Windows, once the Python program will terminate.
The problem is that programmers might (and will) copy the sample code to somewhere in the middle of their application - resulting a memory leak.
Hello
Thank you for informing me about this. It is highly appreciated!
Stefan