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 leak on windows #137
Comments
We noticed a memory leak in pythonnet and it is fixed in pull request for most use cases: |
@pomplesiegel This is interesting. 🤔 Everything you have reported on Your program is doing an infinite loop here. I reckon you are doing this on If this happens to |
@shivaprsdv Great, yes I believe this is a bug as well. Thank you. (removed my original end of this post) |
You do not need to call destroy_window to close the window by pressing the X button. This case is already handled by webview. As Shiva said Invoke eval stuff is implemented on purpose to get a return value from the evaluated code. |
Hi @r0x0r, I apologize for getting off topic. I removed the second half of my post. |
The leak should be real. Although it doesn't happen on Mac as the OP pointed Normal on Mac:Simulated:The issue is simple: every time we call Leak or not, ideally we should be deleting the script element after it accomplishes |
I see the problem now, but this is how the Windows implementation works. The problem is that Windows does not provide a way to run arbitrary Javascript, but instead is able to run a named function. So in order to run Javascript code, it must be wrapped into a named function, which will be called (wrapped inside an eval to get its return value). Given all that, the function will stay in memory. |
Great, thank you! |
@r0x0r Could add the code to delete the function along with the |
Gave it a go and found out the following
The next step will be encapsulating an invoke function inside an object and see if WinForms is able to call that. It is late here though, I will give it a go at a more appropriate time. |
This is what I found out:
I would try: def _evaluate_js():
...
code = 'function {0}() {{ {0} = null; return eval("{1}"); }}' # 1.
code = code.format(function_name, _escape_string(script))
...
self._js_result = document.InvokeScript(function_name)
self._js_result_semaphor.release()
script_element.OuterHTML = '' # 2.
... |
@pomplesiegel Can you check whether this solves the problem? I have no way to test it. |
Hi @shivaprsdv, thanks for the update! I just checked out and ran this branch on windows and unfortunately the memory leak still persists on Windows. I'm happy to try anything further. |
I must have overlooked something. Seems like the functions aren't being garbage |
Sure @shivaprsdv, i just ran it w/ the program printing a return value of return document.getElementsByTagName("script").length; and this value is growing rapidly. If I print the last value of the script array as it grows, i get something like function invokee3399462b44a11e7a86110f0050b27cc() { invokee3399462b44a11e7a86110f0050b27cc = null; return eval("doNothing()"); }
function invokee33b6676b44a11e78de910f0050b27cc() { invokee33b6676b44a11e78de910f0050b27cc = null; return eval("doNothing()"); }
function invokee33d7938b44a11e7af7010f0050b27cc() { invokee33d7938b44a11e7af7010f0050b27cc = null; return eval("doNothing()"); }
function invokee33f8988b44a11e7805810f0050b27cc() { invokee33f8988b44a11e7805810f0050b27cc = null; return eval("doNothing()"); }
function invokee341662eb44a11e7852210f0050b27cc() { invokee341662eb44a11e7852210f0050b27cc = null; return eval("doNothing()"); }
function invokee34348dab44a11e7a62610f0050b27cc() { invokee34348dab44a11e7a62610f0050b27cc = null; return eval("doNothing()"); }
function invokee3456474b44a11e79fde10f0050b27cc() { invokee3456474b44a11e79fde10f0050b27cc = null; return eval("doNothing()"); }
function invokee34773e6b44a11e79c7210f0050b27cc() { invokee34773e6b44a11e79c7210f0050b27cc = null; return eval("doNothing()"); } |
Good find. I haven't thought of using eval directly, I will give it a go. |
I pushed a revised version to the master. For some reason it refuses to work with the escaped script, but the original script works like a charm (with line breaks and line comments) |
Hi @r0x0r, thanks for the update! This is an improvement, as the size of the scripts is no longer increasing. However I do still see a fairly fast leak with my empty program from above: About 1MB every 20s. Do you see this on your side as well using Task Manager? |
@r0x0r Have you checked there is no need to escape even double quotes? 😃
@pomplesiegel May be this is normal, seeing you're running an intensive infinite |
Hi @shivaprsdv, i just checked this. The program does not grow when calling |
Is there any way to check the behaviour of this program (or something similar) on |
Here is what I found out.
|
Great, thanks for looking into this. I'm happy with this as a result - was just trying to be thorough. Shall we consider this closed? |
Yes please close.
|
There appears to be a memory leak on Windows, occurring whenever
webview.evaluate_js()
is called. I'm using pywebview v1.7 + "pythonnet" on Windows 10 64bit, with python3.6.2. The same issue does not exist on mac.Code to reproduce (most trivial example I could come up with)
Then watch the memory usage of the program grow in the task manager. The memory usage on Mac remains static when running this program.
In order to further investigate, I later changed doNothing to
which, when printed in python, made it clear that the number of script elements is growing (and never shrinking) with each call to
evaluate_js()
. Not sure if that's the expected behavior.Finally, if the value of those script tags is printed, we see something like
function invokecb2c8066aea211e7849010f0050b27cc() {return eval("doNothing()")}
which over time monotonically grows to higher values
up and up.... Are these pointers to resources in windows that never get cleaned up, or are they just GUIDs?
Happy to provide any more info.
Really enjoying the library, btw! Hoping to resolve the memory issue on the windows side so I can use it further.
The text was updated successfully, but these errors were encountered: