AbsolutePath.ReadKind allocates a new 16 KiB buffer per directory on Windows: the pooled buffer is not returned on failure
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
Research direction
Start with TruePath/DiskUtils.cs, especially TryGetReparseDataBuffer around the ArrayPool<byte>.Shared rent and DeviceIoControl failure return; then trace how AbsolutePath.ReadKind() calls it on Windows. Reproduce the reported allocation with the provided loop and check existing tests for Windows path kinds. Done when ordinary directories reuse or avoid the rented buffer and the allocation drops without changing reparse-point results.
Written by the indexing model from the issue text.
Description
AbsolutePath.ReadKind() on Windows ends up in DiskUtils.TryGetReparseDataBuffer for every directory. The method rents a 16 KiB buffer from ArrayPool<byte>.Shared, but returns it only on the success path. For anything that isn't a reparse point (i.e. almost every directory), DeviceIoControl(FSCTL_GET_REPARSE_POINT) fails, the method does an early return null, and the rented buffer is dropped. Every call then allocates a fresh 16 KiB array instead of reusing the pooled one.
Measured on ReadKind() (allocated bytes per call):
- a file: 41 B
- a directory: 16,480 B
Repro:
var dir = new AbsolutePath(Path.GetTempPath());
for (int i = 0; i < 100; i++) dir.ReadKind(); // warmup
var before = GC.GetAllocatedBytesForCurrentThread();
for (int i = 0; i < 10_000; i++) dir.ReadKind();
Console.WriteLine((GC.GetAllocatedBytesForCurrentThread() - before) / 10_000); // ~16480
This is not a correctness failure, but it defeats the pool and produces a lot of garbage in directory-walking code.
Recommendations
- Return the buffer on the
DeviceIoControlfailure path too.DeviceIoControlhas finished writing by then, so this is safe (the "abandon rather than return" advice only applies to buffers that might still be in use). - Alternatively, rent the buffer only when it is actually needed:
ReadKind()already reads the attributes, and a junction always hasFileAttributes.ReparsePointset, so the reparse query can be skipped for everything else. (A 16 KiBstackallocis not a good replacement for the pool: it is well above the ~1 KB guideline for stack buffers.)
- Dominant language
- C#
- Stars
- 107
- Forks
- 22
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 13
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from ForNeVeR/TruePath
-
Wrong values of Kernel32.FileShare.Delete and Kernel32.FileAttributes.PosixSemanticsPossibly taken @ElectLive claimed this 1 day ago. Openbug good first issue help wanted
Difficulty 1/5 Under an hour Newbie friendliness 83/100
ForNeVeR/TruePath#241 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement good first issue help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
ForNeVeR/TruePath#165 · 2 comments ·
Maintainers usually reply within 1 day
-
Windows tests: symlink access requires dev mode or elevated accessPossibly taken @hamdiakin claimed this today. Opendocumentation help wanted
Difficulty 3/5 1-2 days Newbie friendliness 57/100
ForNeVeR/TruePath#245 · 1 comment ·
Maintainers usually reply within 1 day
-
bug good first issue help wanted
Difficulty 3/5 Half a day Newbie friendliness 57/100
Maintainers usually reply within 1 day
-
enhancement help wanted
Difficulty 5/5 Over a week Newbie friendliness 35/100
Maintainers usually reply within 1 day
All issues in ForNeVeR/TruePath
Similar issues
-
bug priority: P2
Difficulty 1/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
Maintainers usually reply within 1 day
-
[Docs] README/PRIVACY still name AppCenter although v1.5.6.0+ uses the Microsoft Store Services SDKOpen
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Azure/azure-sdk-tools#17317 ·
Maintainers usually reply within 1 day
-
Test
Difficulty 2/5 1-3 hours Newbie friendliness 69/100
Maintainers usually reply within 1 day