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
Add DisposalHelper class #7334
base: master
Are you sure you want to change the base?
Add DisposalHelper class #7334
Conversation
I don't quite see the need for this. As far as I understand, if an exception occurs when disposing a resource, that is a bug that has to be fixed on the app itself and the potential memory leak in that scenario will disappear as soon as it's fixed. I see it may add some convenience not to have to do some null checks but I'm not sure it justifies the overhead. |
Overhead is not big and only occurs at disposal phase. So, I believe it worth it. |
I think adding a new class and new exception is a bit overkill. |
I agree |
Probably "overhead" was a wrong choice of words, I meant too much complexity for something simple (such as adding a whole new Exception class), maybe "overkill" would be more appropriate. The use case regarding I still don't see all those use cases in which this is useful. This doesn't fix non detected bugs in apps, it may just potentially prevent some memory leak in a buggy app by crashing the app a bit later or avoiding the crash altogether (disposeSilently) by swallowing exceptions (which I wouldn't recommend but that's something that can be done easily with a simple try catch block withouth the need for this). It'd also be limited to games that manually dispose stuff and don't use |
Well, idk. My vision is that overall it's good to wrap some constantly repeatable actions into some single unit (class or method) with convenient interface and use it even if it looks a bit complex inside. I agree "silent" methods might be dangerous, I can remove them. But what about other parts of DisposalHelper? I still believe it's good thing to have. P.S. anyway thank you for paying attention on my PR! |
I personally don't really see the need for this at the framework level - it feels like an application layer utility. |
From my experience, everything in libgdx is safe to double dispose. I'd argue that everything should be safe to call dispose on multiple times. Ideally you should never end up doing it, but it shouldn't be a pitfall if you do. |
I don't know your experience. But I'm pretty new here and already faced a case when
TBH, I don't know how to correctly dispose Skin object in my case without this change (and without reflection magic). If you interested in details, here is an example on Kotlin: And skin.json part: |
Oh, looks like you're right. I wonder why we throw an exception instead of just ignoring the second call. |
I think your scenario is probably more correctly described as a question of resource ownership - in other words, Skin doesn't know that it doesn't own the resource you are providing (the BitmapFont) and tries to dispose of it when the skin is disposed. In the snippet provided, there is not enough surrounding code to tell but I assume the ownership of the bitmap font is retained by the caller and it is disposed separately from the skin. To me, it would be worth looking into whether Skin should know that it doesn't own a resource and not try to dispose it. |
I create font in the next way: And I do not store it anywhere out of I know, this case may be fixed. Someone is going to say I'm doing something wrong. I agree, but this example works OK except the disposal issue. And how many more situations are possible were owning was not correct and the only result of it is just double disposing? Idk, but again, at the moment of creating this PR I assumed these situations may occur pretty frequent. |
I've created #7347 independently of a possible proper fix in |
DisposalHelper is designed to help with disposal process of multiple resources. There could be a potential memory leak when exception occurs while disposing multiple resources. DisposalHelper provides handy way to avoid such situation.
Skin class was updated to use DisposalHelper to show an example of usage.
Here is another one-line example:
DisposalHelper.disposeAll(batch, font /* any other resources that have to be disposed one by one */);