-
Notifications
You must be signed in to change notification settings - Fork 16
Exceptions can use up large amounts of memory #43
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
Comments
Example code: import gc
import asyncio
def show_mem(text: str):
gc.collect()
print(f"{text} mem: {gc.mem_alloc()}")
async def crashing_routine(obj):
print(f"object is {len(obj)}")
show_mem("Before crash")
await asyncio.sleep(0.5)
raise RuntimeError("Crash")
async def main():
show_mem("Before large_object creation")
big_object = bytearray(8000)
show_mem("After large_object creation")
asyncio.create_task(crashing_routine(big_object))
await asyncio.sleep(2)
show_mem("Before running")
asyncio.run(main())
show_mem("after crash")
asyncio.run(main())
show_mem("after second run") Output:
As you can see |
I think this could be fixed by simply generating a context dict on the fly before calling |
If you have the inclination to try your hypothesis, and it works, a PR would be welcome. Nearly all the code in this library is copied from the MicroPython asyncio implementation: https://github.com/micropython/micropython/tree/master/extmod/asyncio. It's worth checking the latest version of that to see if it's changed. |
No new changes in the micropython version. I'll submit a PR shortly. Is it worth submitting the same issue in the micropython repo? |
I don't know if their traceback handling is as extensive as ours, but it sounds like a good idea! |
There's actually a fair bit of context held in the event loop, so I've just made it so that creating a new event loop clears all the previous references. I was also wondering if it was a deliberate decision to have a global |
The intention is that only one event loop is supported, so maybe it was just a shortcut? I think you could ask this question in discussions (or make an issue) in the MicroPython rep. There is also an #asyncio channel in their discord. |
OK, I looked at the code, and see what I said is overly obvious :) . Also I looked back at the blame history, and there's no churn in |
Uh oh!
There was an error while loading. Please reload this page.
If an exception occurs in a task which is not the "main task", the exception is stored in a global variable:
_exc_context
incore.py
. This is then passed tocall_exception_handler
. The exception contains the full traceback at the point of error - which includes references to multiple objects at the time of the error. These objects cannot then be garbage collected until the next exception occurs and_exc_context
is overwritten. In complex programs this can cause large amounts of memory to be usedThe text was updated successfully, but these errors were encountered: