-
Notifications
You must be signed in to change notification settings - Fork 181
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
Shutdown #937
Shutdown #937
Conversation
Codecov Report
@@ Coverage Diff @@
## master #937 +/- ##
==========================================
- Coverage 87.76% 87.66% -0.10%
==========================================
Files 112 114 +2
Lines 10011 10069 +58
Branches 4045 4048 +3
==========================================
+ Hits 8786 8827 +41
- Misses 622 634 +12
- Partials 603 608 +5
Continue to review full report at Codecov.
|
This pull request introduces 1 alert when merging 800a363 into 505da82 - view on LGTM.com new alerts:
|
@marscher Is the style of these config options acceptable? |
jpype/_core.py
Outdated
@@ -96,6 +96,10 @@ def decorate(func): | |||
|
|||
|
|||
def isJVMStarted(): | |||
""" This method is horribly named. It should be named isJVMRunning as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be a comment (e.g. TODO), but not a docstring IMO. It is confusing for the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any recommendations for a docstring as it doesnt do what its name implies? This has been bothering me for a while. We have three states being described by one bool flag: jvm not started, jvm running, jvm shutdown.
# We are exiting anyway so no need to free resources | ||
if _jpype.isStarted(): | ||
_jpype.JPypeContext.freeResources = False | ||
if jpype.config.onexit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it be possible to cover this in the tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can hit each path but I am unsure what to test for as these options are mostly about how much memory to free. Agressively clearing memory just to call exit is an invitation to trigger race conditions. But what behavior change should should be tested for here?
@@ -560,7 +566,7 @@ static PyObject* PyJPModule_isPackage(PyObject *module, PyObject *pkg) | |||
} | |||
|
|||
|
|||
#if 0 | |||
#if 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you expect to use this debug code in the future? If not, I recommend getting rid of it. It is stored in the history of the file anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a leak for another PR. This particular test code gets used whenever I debug memory issues with slots. It was reactivated for #933. Maybe i should just tag it as a branch as it is likely to get reused. Or perhaps on the instrumentation compile flag.
# based on these will be valid in all future versions. | ||
# | ||
|
||
onexit = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This style is plain and simple and could be replaced with something more complicated (if ever needed) in the future. So I completely agree with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the name config reasonable? Is there any other behaviors that should be configurable in this way besides shutdown?
The basic idea is if there were multiple modules using jpype then the config module could gather all the requirements. Most modules would use default so would never set these options. This avoids having a huge number of options to startJVM and requiring the main from having to gather up all module requirements explicitely.
char freeJVM = true; | ||
|
||
if (!PyArg_ParseTuple(pyargs, "bb", &destroyJVM, &freeJVM)) | ||
return NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a subrun would be nice to cover this behavior as well.
I hope these potential leak checks on osx-py39 are false positives... |
The mac leaks are false positives. There is nothing that requires memory to be cleaned up on requests for gc and unless the gc is a true stop the world the request may not be complete before we gather statistics. It is sort of a hint. If there was a leak it should steadly increase rather than failing to shrink a few times which is what triggers this check. We can reduce the false positives by running larger batches or waiting longer for the gc to complete. But both options cause the test bench to run more slowly. |
@marscher it was pointed out in the JNI documentation that unloading the JVM is not supported. Should the default be |
Yes. But whats the point of offering an option for an unsupported feature anyways? |
We can remove the From the bowels of the jpype git history jvm unloading was introduced in
I am not sure why we free the shared library in the first place other than an attempt to keep memory from leaking. Most codes do not attempt to free a loaded shared library because handlers added into memory would likely cause a segfault unless something specifically goes and uninstalls every connection. If unloading the library is unnecessary (or unwise) I can certainly clean up some code by removing that from the platform handlers. But honestly I am not sure what the JNI documentation is trying to indicate. In JNI version 7 it says....
(our problems mostly stem from the last statement, there is no way that I know to ensure that Python threads has deleted any contact to Java nor has a Java method on the call stack.) And later it says...
So does that last statement mean
|
if _jpype.isStarted(): | ||
_jpype.JPypeContext.freeResources = False | ||
if jpype.config.onexit: | ||
_jpype.shutdown(jpype.config.destroy_jvm, False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't understood why we wouldn't want to use jpype.config.free_jvm
instead of the False
literal here. Is this a mistake, or intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no point in freeing if we are 90% of the way to exit. Is there?
I haven't the time to test all the options as a subrun mostly because it is hard to know what the tests should be. At most we can just run coverage tests to see if each fails. This should go in 1.3 |
Test PR. Not clear it this deals with the issue.