Laden...

HttpUtility.HtmlEncode mit MemoryLeak

Erstellt von Programmierhans vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.392 Views
Programmierhans Themenstarter:in
4.221 Beiträge seit 2005
vor 10 Jahren
HttpUtility.HtmlEncode mit MemoryLeak

Heute per Zufall entdeckt:

HttUtility.HtmlEncode ist von Microsoft extrem stümperhaft implementiert. In den von dieser Methode aufgerufenen Funktionen werden StringWriter verwendet... diese befinden sich aber weder in einem using noch wird ein Dispose aufgerufen... somit ist man auf die Gnade vom GC erlöst zu werden angewiesen.

Edit: Betrifft nur die Variante welche einen String als Input hat... man kann auch selber einen Wrapper schreiben welcher den StringWriter selber erstellt und nachher disposed.

--> besser den HtmlEncode selber machen... dann leakt es nicht und ist je nach Implementierung auch noch schneller.

Gruss
Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

16.806 Beiträge seit 2008
vor 10 Jahren

Ich benutze Microsofts AntiXSS Library

AntiXSS.HtmlEncode(myString);

Ich hab' jetzt aber nicht geforscht, ob dieser "Bug" ebenfalls dort enthalten ist...

Programmierhans Themenstarter:in
4.221 Beiträge seit 2005
vor 10 Jahren
AntiXSS.HtmlEncode(myString);  

Nein die scheint sauber zu sein.

Gruss Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

S
417 Beiträge seit 2008
vor 10 Jahren

Hi,

also die Aussage "extrem stümperhaft" ist übertrieben.
Ich gebe dir zwar recht, dass das fehlende Dispose unschön ist, aber im genannten Fall hat es ohnehin keine Bedeutung, da weder StringWriter, noch die Basisklasse TextWriter irgendwelche Resourcen innerhalb der Dispose-Methode freigeben und damit ein fehlendes Dispose keine Speicherproblem verursacht.

Programmierhans Themenstarter:in
4.221 Beiträge seit 2005
vor 10 Jahren

Ich verwende den HtmlEncode in der Code-Generierung auf dem CodeDom... um Comments aus Metadaten in den Code rein zu generieren....

D.h: ich rufe innerhalb weniger Sekunden HtmlEncode mehrere 10'000 mal auf... und dann macht es sehr wohl einen Unterschied... alle diese Writers warten auf den GC... und bei einer sauberen Implementierung würde der Speicher sofort freigegeben.

Mit Microsoft-Implementierung: Abbruch bei knapp über 3 GB Speicherverbrauch... nach Umbau auf eigene Implementierung bleibt der Speicherverbrauch von Visual Studio unter 900 MB..

Klar ist ein extremes Beispiel (ich generiere 388'415 Zeilen Code... und davon sind sicher mind. 10 % Kommentare).

Gruss
Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

5.657 Beiträge seit 2006
vor 10 Jahren

Hi Programmierhans,

wie oben schon erwähnt, sollte das eigentlich keine Auswirkungen haben, da die betreffenden Klassen in der Dispose-Methode sowieso keine Resourcen freigeben. Außerdem betrifft die IDisposible-Schnittstelle nur _unmanaged _Resourcen, der GC kümmert sich dagegen um _managed _Resourcen. Unabhängig davon bestimmt der GC selbst, wann er den Speicher abräumt, er wird nicht durch den Aufruf von Dispose dazu angewiesen. Deshalb dürfte das für deinen Anwendungsfall kein Problem darstellen.

Christian

Weeks of programming can save you hours of planning

849 Beiträge seit 2006
vor 10 Jahren

Hallo,

weis nicht ob es damit etwas zu tun hat, aber ich hatte neulich den Fall das bei einer Anwendung wo ich in einer Schleife Reports erstellt habe der Speicherverbrauch auch immer höher gegangen ist, bis dann das Studio die Grätsche gemacht hat. OutOfMemory. Im Release hingegegen (ohne Debugger) ist die Anwendung zwar immer wieder bis zu einer Grenze von ~3GB gegangen, dann hat aber der GC zugeschlagen und die ANwendung ist wieder auf ein paar KB runtergegangen.
Und dann immer rauf <-> runter bis die Reports durch waren.

Als wenn das VS da irgendwas blockiert oder sich Referenzen hält..

Programmierhans Themenstarter:in
4.221 Beiträge seit 2005
vor 10 Jahren

Ich habe jetzt aufgrund der Kritiken das ganze in einem Minimalprojekt nachgebaut. Kein erhöhter Memoryverbrauch sichtbar... aber es handelt sich bei mir um einen CodeGenerator (der ist 32-Bit und wird aus VS mit Java aufgerufen... und da ist der Unterschied massiv)...

(Und es ist definitiv der einzige Unterschied gewesen zwischen den Tests).

Wieso auch immer

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

T
2.219 Beiträge seit 2008
vor 10 Jahren

@ProgrammierHans
Hab mir mal den HtmlEncode Code in ILSpy angeschaut.
Die Programmierung ermöglicht keinen Memory Leak.

StringBuilder brauchen auch kein Dispose, da diese intern String über unmanged Code verknüpfen.
Intern wird dann der String gespeichert.

Dies wird durch den GC aber im Endeffekt auch weggeräumt.
Alternativ kannst du aber über die GC Klasse mit der Collect Methode deinen Speicher alle paar Sekunden mal aufräumen lassen.

Wenn du endlos die Methode aufrufst, wird es für den GC auch schwierig immer den Speicher sauber zu halten.
Hier wäre auch zu prüfen wie der Aufruf deines Genereators erfolgt.
Ohne Code würde ich eher davon ausgehen, dass das Problem bei deinem Code liegt.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.