zui > edb.programmering.* > edb.programmering.dotnet

Rick (04.03.2010, 00:25)
Hej I gruppen,

Jeg får en streng, som er blevet komprimeret med et gzip stream. Denne skal
afleveres som en streng, der er dekomprimeret af den komprimerede. Jeg er
kommet frem til følgende metode:

public static string Decompress(string compressedString)
{
string decompressedString = string.Empty;
using (MemoryStream ms = new MemoryStream())
{
using (MemoryStream msCompressed = new
MemoryStream(Convert.FromBase64String(compressedSt ring)))
{
using (GZipStream gzStream = new GZipStream(msCompressed,
CompressionMode.Decompress))
{
byte[] buffer = new byte[BUFFER_LENGTH];

int readDataCount = gzStream.Read(buffer, 0, BUFFER_LENGTH);
while (readDataCount > 0)
{
ms.Write(buffer, 0, readDataCount);
readDataCount = gzStream.Read(buffer, 0, BUFFER_LENGTH);
}
}
}
ms.Position = 0;
using (StreamReader reader = new StreamReader(ms))
{
decompressedString = reader.ReadToEnd();
}
}
return decompressedString;
}

Metoden virker helt som den skal. Det er komprimeret XML, der kommer ind og
en udpakket XML, der går ud. Komprimeringsfaktoren ligger omkring de 1:10

Mit problem er imidlertid, at jeg skal til at bruge metoden til større xml
strenge. Dvs. komprimerede strenge på en 6-10mb, der kommer ind bliver
60-100mb når de kommer ud og så sker det, at jeg får out of memory
exception. Nogle gange sker det i while loopet og andre gange i
streamreaderen.

Der er ca. 768mb i maskinen. Vil mere ram i maskinen løse problemet eller
bør metoden være anderledes?
Umiddelbart har jeg fået det interface at det skal være en streng ind og en
streng ud og har ikke lige adgang til at lave det om.

- rick -
Arne Vajhøj (04.03.2010, 03:04)
On 03-03-2010 17:25, Rick wrote:
[..]
> eller bør metoden være anderledes?
> Umiddelbart har jeg fået det interface at det skal være en streng ind og
> en streng ud og har ikke lige adgang til at lave det om.


RAM skulle kun betyde noget for hastigheden.

På 32 bit Windows har din app knap 2 GB virtuelt adresserum
at boltre sig på uanset RAM.

Lidt RAM => langsomt, meget RAM => hurtigere.

Så vidt jeg kan se har du:

base64 encoded compressed string = 2*1.333*X bytes
compressed byte array = X bytes
decompressed byte array = 10*X bytes
decompressed string = 2*10 bytes
ialt = 33.333*X bytes

Så umiddelbart burde der være plads til de størrelser
du nævner. Måske er der noget andet som har et stort
memory forbrug??

Hvis du skal reducere memeory forbruget her, så må
tricket være at i.s.f. at konvertere det hele i memory, så
at processe en lille del af gangen. Det kræver dog en
stor ændring af logikken.

Arne
Rick (04.03.2010, 08:49)
"Arne Vajhøj" <arne> skrev i meddelelsen
news:6298
[..]
> tricket være at i.s.f. at konvertere det hele i memory, så
> at processe en lille del af gangen. Det kræver dog en
> stor ændring af logikken.


Mange tak for det udførlige svar.
Ja, så kan jeg godt se, at der burde være nok. Alligevel lidt skræmmende at
se det regnestykke :o)
Jeg prøver at frigive al den hukommelse som jeg kan, hver gang at det er
muligt.
Jeg har opdaget, at metoden faktisk virker de første par gange, men herefter
begynder der at komme outofmemory. Mine erfaringer med GC er ikke særlig
store, men kunne en
GC.Collect();
GC.WaitForPendingFinalizers();
i starten af metoden måske hjælpe?

- rick -
Arne Vajhøj (04.03.2010, 17:45)
On 04-03-2010 01:49, Rick wrote:
[..]
> GC.Collect();
> GC.WaitForPendingFinalizers();
> i starten af metoden måske hjælpe?


Nej.

..NET runtime vil selv lave garbage collection inden du får
out of memory exception.

Arne
Lignende emner