-
Notifications
You must be signed in to change notification settings - Fork 189
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 with cpSpaceGetBodyPositions? #235
Comments
Thanks for the report. I will have to investigate a bit, seems like its not just the array because that should get free'd for each iteration. I also tried to call ffi.release on it, but that didnt help so have to check more carefully. ps. If you later do something with the batched stuff please let me know. Would be great to hear some realworld experience of that (if it turns out to be very useful I will make it part of the Python Pymunk API directly, but first I wanted to see if someone actually used this feature) |
Thanks for the feedback. I will definetelly use the batched api if I can solve the memory issue because I need to retrieve positions quite often. Otherwise, I will loop over the bodies. In any case, I'll let you know when the stuff is ready. |
Ok, now I checked more carefully and its the internal array ( You can work around this by re-using the array each time. Just set its num to 0 and it will behave as an empty array. In a real-world scenario this would also be preferable, since then the array doesnt need to be recreated each loop iteration.
I also remember why I only made an experiment and didn't make it into a full API at the time. Just getting the positions of all bodies is a bit limited. Lets say you have bodies that are not identical in the simulation, maybe they are circles and squares, and you want to draw them. Then it doesn't help to get an array of all positions unless you can map it to circle or square body. When I think about this issue again what Im leaning towards is to have 3 functions: one to get positions of all bodies, one to get angle of all bodies and finally one to get body ids. All 3 methods would return the data in the same order, so that as long as you know how to handle different ids you could map it with the body_id array. I think body position and body angle is the most important data. Other things doesnt normally change every step so can be fetched with the normal non-batched functions if needed. Do you have some suggestions or comments? Does it sound reasonable, or is there another way? |
Thanks for the workaround! That seems reasonable. In my view positions, angles, and the existence of contact as well as the interpenetration distance are the more important metrics. Regarding body ids, so far I assumed that pymunk and chipmunk preserve ordering, although I did not run extensive validation. Thus, I store this information at body creation and I use the index of the returned data to map them to the bodies. |
There is no guarantee, but I think as long as no bodies are removed the order will be the same. If bodies are removed Im not sure if the order will be kept.. Anyway, I think I dont want to guarantee the order even if it works that way now. Then I have two more questions:
|
Does it make sense to you? |
I have fixed the memory leak issue and cleaned the functions a bit so there's a new and free function to use. And I updated batched benchmark code to not allocate a new array for each iteration, so its more obvious whats the best way to do things. I also modified the function to return both positions and angles in two separate arrays. However, Im still not sure about how to best wrap this up into a more proper batched pymunk api, that can also support more cases (like contacts or other properties on the body) in a nice way. Thanks for the followup, its great with some real feedback on whats useful and why 👍 . But how to best make the api is a different question, have to think a bit more about that. |
Thanks for addressing the issue! I updated pymunk and tried to run the benchmark. It works fine with 1 body, but not with more. I am not sure why, I will try to investigate more.
|
Oh! For me the benchmark ran fine without issues. But now I re-read the code and noticed some things in the c-code that might create issues. Maybe its dependent on OS and python version (or its just random) if it works anyway or breaks. Right now the batching is not really part of the public API of Pymunk, its more of an experiment, so there's no test that runs on built etc. Regardless I pushed an update that might fix it. If you have the possibility it would be great if you could try it. There are pre-built wheels here: https://github.com/viblo/pymunk/actions/runs/6631724385 (you probably need to first uninstall pymunk, then install the specific wheel matching your environment directly) |
Yes, I can confirm the last wheels run on my machine (Ubuntu 23.04). |
I got inspired and coded together an proper pymunk api for batch. Its now released in Pymunk 6.6.0. If you try it out and have some feedback, dont hesitate to share it :) |
Hi,
First, thanks for this amazing work.
I have been toying with the
cpSpaceGetBodyPositions
used in the batched position benchmark as a way of improving performances by not looping over each body.I noticed that memory usage accumulates over iterations which seems to indicate that the memory used by
cpSpaceGetBodyPositions
is never released. I tried few approaches to force the garbage collection during the iteration, but this is my first contact withcffi
and I had no success so far. Of course, I might be doing something totally wrong.Here is a MRE:
This results in a python process using 8.6 GB of memory on my machine.
The text was updated successfully, but these errors were encountered: