Marshalling of byte[] arrays is causing excessive GC load (and gen2 collections)
See original GitHub issueMy app was serving a large file (~2 GB) through Dokan and I was noticing a gen2 garbage collection every second. This is obviously not good for performance - I was seeing 30% of CPU spent in GC. After investigating, it turns out the allocations were coming from marshaling of the byte[] array in ReadFile(). A managed array was being allocated for every ReadFile() call and thrown away after the call completes.
Today’s code looks like this:
public delegate NtStatus ReadFileDelegate(
[MarshalAs(UnmanagedType.LPWStr)] string rawFileName,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), Out] byte[] rawBuffer,
uint rawBufferLength,
...
);
By modifying it to not marshal at all and just pass the IntPtr
I was able to completely eliminate the GC load. The implementor of IDokanOperations
can then use Marshal.Copy
or unsafe code to fill the output.
This is obviously a breaking interface change, but maybe it’s worth adding a new interface, something like IDokanOperationsUnsafe
, for those that want the perf?
Issue Analytics
- State:
- Created 5 years ago
- Comments:9 (9 by maintainers)
Top GitHub Comments
See PR #206 for the implementation of this feature.
#206 merged to master, closing issue.