-
Notifications
You must be signed in to change notification settings - Fork 94
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 in Gamepad.GetState #3
Comments
I've been trying using XInputDemo.exe and looking at the "private bytes" in Process Explorer, it didn't change at all after 5 minutes of active input (moving the sticks, triggers, etc.). It was stable at around 12MB, and the .NET Perf tab of the process didn't show any garbage collection activity or any increase in the heap size. XInputDemo.exe does a while(true) loop as well, I even replaced its loop with the code you pasted to be sure. I suspect it might be somewhere else in your code. Can you create a small Program.cs (like the one for XInputDemo) which reproduces the issue please? Thanks. |
I don't see the same behaviour running the unmodified XInputDemo on Windows 7 x64, in Debug I get around 5.7MB stable. I'm willing to help you but I don't want to switch to 8.1 just yet. It's unlikely it's XInputDotNet itself, the code doesn't allocate much in the first place, and all it allocates is structs which should not be a problem. It's also a stateless system (like the native XInput) so I don't see what would cause that at all. |
I don't see how this can be happening, if someone has an idea please re-open this issue. |
I noticed this issue myself recently. It is happening. The issue is use of Marshal.AllocHGlobal without a corresponding Marshal.FreeHGlobal in GamePad.GetState(). Regardless of what you're doing with the memory after you allocate it, you have to free it or it will create a leak. MSDN has more information on Marshal alloc/free usage: The fix should be as simple as adding "Marshal.FreeHGlobal(gamePadStatePointer);" directly after the PtrToStructure call in GetState(). Since the result of that call places the data in managed memory, you no longer need the unmanaged allocation at the point. |
Indeed, I don't know how I didn't see that, this particular has been there for 5 years... I wonder why I wasn't seeing any problems with that on my machine. Anyway, I'll fix it as soon as possible. Thanks. |
To be fair, it's only leaking about 20 bytes per allocation which would be hard to spot if you were polling one GamePad at 60 frames a second. That works out to 72k per minute. It's not exactly massive. It does get worse the faster you poll and if you poll multiple GamePads. Over time it becomes a problem. We have designers here who leave the Unity editor open for days. So as they start and stop the game, it builds up. We've seen some out of memory issues arise. I'm not willing to say XInputDotNet is for sure the only cause there, but it makes some logical sense given the timelines involved that it at least has some contribution to the issue. Either way, thanks for committing to push a fix in. I'm surprised over the past few years no one noticed it - given the popularity of this plugin. |
New release created containing the fix. Thanks guys for the help 👍 |
I'm testing for hours:
And about 15 minutes, memory use is about 2GB.
The text was updated successfully, but these errors were encountered: