[
  {
    "Id": "230425",
    "ThreadId": "67797",
    "Html": "<p>Hello,</p>\r\n<p>I've read all the articles about&nbsp;memory errors and I'm&nbsp;still not sure why I get an OutOfMemory Exception on the Save() method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>I'm just trying to create an in memory zip file, the lpMemStream variable is the MemoryStream of the file I want to compress.&nbsp; This code works fine until I get to about a 99MB file, then I get the OutOfMemory Exception.&nbsp; I am using version 1.6.3.18. Any ideas?&nbsp; Thanks</p>\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim lobjMem As New System.IO.MemoryStream()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Using lobjZipFile As Ionic.Utils.Zip.ZipFile = New Ionic.Utils.Zip.ZipFile(lobjMem)</p>\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lobjZipFile.AddFileStream(&quot;temp.txt&quot;, &quot;&quot;, lpMemStream)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lobjZipFile.Save()</p>\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mlngLength = lobjMem.Length</p>\r\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return lobjMem<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End Using</p>\r\n<p>Stack trace:</p>\r\n<p>&nbsp;&nbsp; at System.IO.MemoryStream.set_Capacity(Int32 value)<br>&nbsp;&nbsp; at System.IO.MemoryStream.EnsureCapacity(Int32 value)<br>&nbsp;&nbsp; at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)<br>&nbsp;&nbsp; at Ionic.Utils.Zip.CountingStream.Write(Byte[] buffer, Int32 offset, Int32 count)<br>&nbsp;&nbsp; at Ionic.Utils.Zip.CountingStream.Write(Byte[] buffer, Int32 offset, Int32 count)<br>&nbsp;&nbsp; at System.IO.Compression.DeflateStream.InternalWrite(Byte[] array, Int32 offset, Int32 count, Boolean isAsync)<br>&nbsp;&nbsp; at System.IO.Compression.DeflateStream.Write(Byte[] array, Int32 offset, Int32 count)<br>&nbsp;&nbsp; at Ionic.Utils.Zip.ZipEntry._WriteFileData(ZipCrypto cipher, Stream s)<br>&nbsp;&nbsp; at Ionic.Utils.Zip.ZipEntry._EmitOne(Stream outstream, ZipCrypto&amp; cipher)<br>&nbsp;&nbsp; at Ionic.Utils.Zip.ZipEntry.Write(Stream outstream)<br>&nbsp;&nbsp; at Ionic.Utils.Zip.ZipFile.Save()<br>&nbsp;&nbsp;</p>",
    "PostedDate": "2009-09-02T14:28:30-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "230474",
    "ThreadId": "67797",
    "Html": "<p>yes -</p>\r\n<p>What you are doing - storing a 99mb MemoryStream - &nbsp;is a challenge.&nbsp; It has nothing to do with DotNetZip. Think of a&nbsp;MemoryStream as a section of memory that expands its capacity automatically.&nbsp; It's really nice to use, but it's&nbsp;hungry for memory.&nbsp; In particular, it's hungry for memory when it expands.&nbsp;&nbsp;I don't know exactly how a MemoryStream works, but I can make a pretty good guess.&nbsp;&nbsp;When you initially create the MemoryStream, it&nbsp;allocates a contiguous buffer of some fixed size.&nbsp; Let's say it's 1k: &nbsp;1024 bytes.&nbsp; Then you write into the buffer.&nbsp; &nbsp;Each time you&nbsp;write,&nbsp;the&nbsp;logic for MemoryStream checks to see if there is enough space.&nbsp; When you fill up 1k, it has to expand.&nbsp; So it allocates a new buffer.&nbsp; As I said I don't know how it works, but typically auto-expanding objects will double in size with each expansion.&nbsp;&nbsp;&nbsp;So then it allocates a&nbsp;2k buffer, and copies the 1k into it.&nbsp; It frees the original 1k buffer.&nbsp; Then you keep writing, and fill up the 2k buffer.&nbsp; It allocates a 4k buffer, for 6k total.&nbsp; Copy and free.&nbsp; Then you fill up the 4k buffer, and so on.&nbsp; Pretty soon you fill up a 64mb buffer, and it has to allocate a 128mb contiguous buffer.&nbsp; Even if you have a 2gb machine, that might be challenging to do.&nbsp;&nbsp; There may be plenty of memory available, but not necessarily a contiguous chunk of 128mb.&nbsp; So you get a memory error.&nbsp;&nbsp;</p>\r\n<p>Why do you want to put a 99mb zip file in memory?&nbsp; 99mb seems like something that is more appropriately stored in a filesystem.</p>\r\n<p>&nbsp;</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2009-09-02T18:15:06.493-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "230475",
    "ThreadId": "67797",
    "Html": "<p>Also you may want to consider moving to a more recent version of DotNetZip.</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2009-09-02T18:15:48.217-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "230695",
    "ThreadId": "67797",
    "Html": "<p>Thanks Cheeso.&nbsp;&nbsp; I think your reasoning is spot on and I'm not sure what else I can do at this point.&nbsp;</p>\r\n<p>The reason I want to put this file in memory is because I am ultimately passing the bytes of the memory stream to a web service and I was hoping to compress the bytes before I pass it.&nbsp; Even with the overhead of compressing the bytes my web service performs better when the bytes are compessed.&nbsp; I was trying to avoid writing out temporary files on the user's machine.</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2009-09-03T07:39:33.537-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "230748",
    "ThreadId": "67797",
    "Html": "<p>If you want to send 99mb, you are probably <a href=\"http://msdn.microsoft.com/en-us/library/ms731913.aspx\">using a stream</a>&nbsp;to <a href=\"http://msdn.microsoft.com/en-us/library/ms789010.aspx\">do the transfer</a>, is that right?&nbsp;&nbsp;&nbsp; If not, you should change your design.&nbsp; (And if you're using ASMX, you should change your design).</p>\r\n<p>If you ARE using streamed transfer, then you can wrap your Stream with a Ionic.Zip.DeflateStream (or GZipStream, or ZlibStream) on the sending size, and on the receiving side.&nbsp; These classes can compress, and de-compress, as you read or write.&nbsp; They are streams, so they do their work without accumulating data in memory.&nbsp;</p>\r\n<p>There is supposed to be some new compression capability in WCF 4.0, but I don't have any information on it.&nbsp;</p>",
    "PostedDate": "2009-09-03T09:44:37.457-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "230814",
    "ThreadId": "67797",
    "Html": "<p>I am using WCF and passing a stream.&nbsp; (So I guess my design is good ;-)&nbsp;</p>\r\n<p>I've considered streaming using MTOM but I'm unclear whether I need to write special code on the client and server to handle chunking.&nbsp; Does WCF take care of this for you?</p>\r\n<p>It's definitely not a bug in your software, I am having the same memory exception when I try to use an xmlwriter and call writer.WriteBase64(). Even if I try to chunk this method, it errors out because it appears to buffer the data before it actully writes everything out.( Flush doesn't work either)</p>",
    "PostedDate": "2009-09-03T12:02:40.19-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  },
  {
    "Id": "230831",
    "ThreadId": "67797",
    "Html": "<p>I don't know about the xmlwriter and WriteBase64.&nbsp;</p>\r\n<p>Getting back to your use of the DotNetZip library, the exception you showed indicates that you were writing all the data to a memory stream.&nbsp; This isn't what you want.&nbsp;</p>\r\n<p>You want to write all the data to an output stream that does not accumulate the data in a single block of memory.&nbsp;&nbsp; The {GZip,Deflate,Zlib}Stream classes will do that.</p>\r\n<p>It's not a zip file but it is compressed, which is what you want I think.</p>\r\n<p>Did you follow the steps here: <a href=\"http://msdn.microsoft.com/en-us/library/ms789010.aspx\">http://msdn.microsoft.com/en-us/library/ms789010.aspx</a>&nbsp;?&nbsp; Did you enable streaming at the transport level?&nbsp; <span style=\"color:blue\">&lt;</span><span style=\"color:maroon\">httpTransport</span> transferMode=&quot;Streamed&quot; maxReceivedMessageSize=&quot;67108864&quot;<span style=\"color:blue\">/&gt;&nbsp;&nbsp; </span>&nbsp;Can you read the stream at the receiver before the sender has completed transmission?&nbsp;&nbsp;&nbsp; That would prove that streaming is actually working.</p>\r\n<p>I don't see why you'd want to go to MTOM;&nbsp; the idea is to compress the data for transmission, right?&nbsp; That should not mean an attachment.&nbsp; You had the idea to use a zipfile to get the compression you want, but actually it would be easier to just use a compressing stream, which means no attachment, no MTOM.</p>\r\n<p>&nbsp;</p>",
    "PostedDate": "2009-09-03T12:37:39.48-07:00",
    "UserRole": null,
    "MarkedAsAnswerDate": null
  }
]