Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

AbsolutePath.ReadKind allocates a new 16 KiB buffer per directory on Windows: the pooled buffer is not returned on failure

Fermée Adaptée aux débutants
#240 0 commentaires 1 réaction 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 6 jours

@FalconTechDev y travaille déjà.

Depuis le 19/10/2026.

  • #246 par @FalconTechDev — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
78/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
csharp
Domaine
backend

Piste de recherche

Commencez par TruePath/DiskUtils.cs, en particulier par TryGetReparseDataBuffer autour de la location via ArrayPool<byte>.Shared et de la restitution en cas d’échec de DeviceIoControl ; suivez ensuite comment AbsolutePath.ReadKind() l’appelle sous Windows. Reproduisez l’allocation signalée avec la boucle fournie et vérifiez les tests existants pour les types de chemins Windows. Le travail est terminé lorsque les répertoires ordinaires réutilisent le tampon loué ou évitent de le louer, et que l’allocation diminue sans modifier les résultats pour les points de réanalyse.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

enhancement good first issue help wanted

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 DeviceIoControl failure path too. DeviceIoControl has 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 has FileAttributes.ReparsePoint set, so the reparse query can be skipped for everything else. (A 16 KiB stackalloc is not a good replacement for the pool: it is well above the ~1 KB guideline for stack buffers.)
Langage dominant
C#
Étoiles
109
Forks
26
Merge moyen
5 j 13 h
PR mergées (30 j)
9

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de ForNeVeR/TruePath

Toutes les issues de ForNeVeR/TruePath

Issues similaires

Plus d'issues C#

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.