ninia / jep

Embed Python in Java
Other
1.3k stars 147 forks source link

Why pyObject is declared as AutoCloseable? #415

Open Daniel-Alievsky opened 2 years ago

Daniel-Alievsky commented 2 years ago

I see that PyObject class is AutoCloseable. But it does not contain any code like finalizer or cleaner. What will occur if, due to some reasons, I will not use try-with-resources and will not call close() method? Will PyObject (its Python part) be freed by garbage collector or not?

bsteffensmeier commented 2 years ago

PyObject will hold a reference to the Python object until it is closed, the interpreter is closed, or after the object is garbage collected. Whichever occurs first will clear the reference to the Python object. All the memory used by python cannot be freed until that reference is cleared. When it is cleared if python is not holding other references to the object then the memory will be freed. For small objects or short lived interpreters it is likely not necessary to close PyObject. For large and long running interpreters it would be a good idea to close them explicitly. If a PyObject or the Interpreter are not closed then after the PyObject is deleted by the garbage collector Jep will clear the Python reference the next time a new PyObject is created.

Daniel-Alievsky commented 2 years ago

Thank you for explanation. As I understand, real problem with non-closed PyObject may appear only in a situation, when it occupy gigabytes or if we have millions of non-closed PyObject instances. JVM "does not know" about Python memory and will not initiate garbage collection in time, that can lead to out of memory. Right?

On the other hand, when GC is activated, it correctly removes all non-references PyObject instances. So, if we use only 100-200 little PyObject instances simultaneously , we will have no a real risk of memory leak, even our application will work during days or months without restarting (of course, JVM GC will be performed from time to time). Right?

bsteffensmeier commented 2 years ago

Thank you for explanation. As I understand, real problem with non-closed PyObject may appear only in a situation, when it occupy gigabytes or if we have millions of non-closed PyObject instances. JVM "does not know" about Python memory and will not initiate garbage collection in time, that can lead to out of memory. Right?

On the other hand, when GC is activated, it correctly removes all non-references PyObject instances. So, if we use only 100-200 little PyObject instances simultaneously , we will have no a real risk of memory leak, even our application will work during days or months without restarting (of course, JVM GC will be performed from time to time). Right?

Right