473,506 Members | 16,994 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

IStream.Read Memory Leak?

I'm currently writing an application (using Visual Studio 2003 SP1 and
C#) that stores files and additional information in a single compound
file using IStorage/IStream.
Since files in a compound file aren't really useful to a user, I use
the IStream::Read function together with a StreamWriter to extract
single files from my compound document.
When I first tested these functions everything seemed to work fine (and
basically, it does), however the memory usage of the app would
skyrocket every time I extracted a large file and never come down until
I closed the application.
At first I thought I had simply forgotten to clear my buffer, leaving a
global reference behind that stopped the GC from cleaning it up (or
something similar), after more in-depth testing this does not appear to
be the case.
Stepping through the code line by line and watching the memory usage
carefully I could see that memory would be reserved every time I called
the Read-function of an IStream (which is to be expected), but it would
not be freed when I nulled the buffer-array I had passed as the out
parameter.
I would have expected IStream::Read to use the buffer array I pass and
not require much memory beyond that, but even after calling the
Garbage-Collector manually after clearing my objects, the memory stays
in use.
I have tried pretty much anything I can think of, calling
IStream::Release after every read (which is not really feasible in any
case, since I want to read my data in chunks and not realease the
stream after every chunk), using Marshal.ReleaseComObject on the
stream, getting the IntPtr from my buffer array and calling
Marshal.FreeCoTaskMem on it manually, but to no effect, the memory
stays used.
I'm at my wits end with this, I can't possibly live with a memory leak
this enormous, but I also can't think of any way to get my data without
using IStream::Read.
Since I'm currently working with VS 2003/.Net 1.1 I use my own
IStream-Implementation, not the one Microsoft supplies with .Net 2.0.
I did convert my project to VS2005 just to try their IStream-class, but
it seems that that works even less, since their implementation of
IStream::Read takes the last parameter (which should return the number
of actually read bytes) as ByVal and thusly always returns 0, not a
good thing if you want to read data in chunks and need to know when you
are done.
Since I haven't worked with IStream before, it is absolutely possible
that I am simply missing something here, but I have no idea what.
Has anyone else ever experienced behavior like this and could offer
some help on how to make sure Read doesn't gobble up my memory?
Any reply would be greatly appreciated.

Sincerely,
Kevin Wienhold

Nov 2 '06 #1
3 3370
Kevin,

It's hard to comment on your problem without seeing any code. But I
have a hard time imagining a memory leak in the system's
implementation of IStream::Read. It's so widely used, so such a
problem would have been discovered by now.

>I did convert my project to VS2005 just to try their IStream-class, but
it seems that that works even less, since their implementation of
IStream::Read takes the last parameter (which should return the number
of actually read bytes) as ByVal and thusly always returns 0, not a
good thing if you want to read data in chunks and need to know when you
are done.
The last parameter is an IntPtr in this case. You have to pass in a
pointer to a location (sizeof(int) = 4 byte buffer) where the result
should be written and then read it from there.

It's defined this way because it's legal for caller's of Read to pass
a NULL pointer if they don't care about the information.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 2 '06 #2
Thank you for your response.
It's hard to comment on your problem without seeing any code. But I
have a hard time imagining a memory leak in the system's
implementation of IStream::Read. It's so widely used, so such a
problem would have been discovered by now.
I realize that IStream is widely used, that's why I assumed I did
something wrong.
I was just hoping that someone knew some general advice concerning
this. The actual function that does the reading is pretty trivial, so I
guess the error lies elsewhere, but since I have no idea where, it is
hard to decide which parts of the code I should post.
The last parameter is an IntPtr in this case. You have to pass in a
pointer to a location (sizeof(int) = 4 byte buffer) where the result
should be written and then read it from there.

It's defined this way because it's legal for caller's of Read to pass
a NULL pointer if they don't care about the information.
If I use the same implementation .Net 2.0 uses, pass an IntPtr and get
its value after the Read-call using IntPtr.ToInt32(), the value is
always 0.
If I pass the IntPtr as a reference it seems to work fine.
I haven't really worked with many COM objects in C#, so I assumed that
the ToInt32-Function would do exactly what you suggested, reading 4
bytes from memory from where the pointer points to and convert them
into an integer.
I'll see what happens when I read the memory manually, it would be
better to stick to the suggested interface declaration without the ref.

Sincerely,
Kevin Wienhold

Nov 3 '06 #3
A small addition:
After getting an IntPtr through Marshal.AllocCoTaskMem(sizeof(int)) I
was able to read a non-zero value from the pointer using ToInt32, I
didn't initialize the IntPtr properly before.
However the value this returns doesn't match the bytes read.
I read data from the stream in chunks 1 MB in size (so just over 1
million bytes), the value returned from IStream::Read after reading one
chunk is over 68 million and never becomes zero, even if I pass 0 as
the second parameter.

Nov 3 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
2987
by: Jason K | last post by:
Let me preface this by saying this obviously isn't a C++ *language* issue per se; rather probably an issue relating to quality of implementation, unless I'm just misusing iostream... I wrote a...
8
3394
by: ranjeet.gupta | last post by:
Dear All Is the Root Cause of the Memory corruption is the Memory leak, ?? suppose If in the code there is Memory leak, Do this may lead to the Memory Corruption while executing the program ? ...
3
15264
by: MJB | last post by:
I'm getting an IStream back from function xmlHttp.responsestream. I would like to convert this to a System.IO.Stream in order to work with it in my application. Has anyone encountered this and...
4
3526
by: Johannes Zellner | last post by:
Hi, how can I extract the whole rest of an istream? (All characters which have not been consumed yet?) -- Johannes
13
10950
by: Gianni Mariani | last post by:
What I would like to do is read bytes from a stream, any number and any time. I would like it to wait until there are any bytes to read. I want the exact same functionality as cstdio's "fread"...
21
6870
by: Peter Larsen [] | last post by:
Hi, I have a problem using System.Runtime.InteropServices.ComTypes.IStream. Sample using the Read() method: if (IStreamObject != null) { IntPtr readBytes = IntPtr.Zero;...
7
5200
by: john | last post by:
I am reading TC++PL3 and on page 644 it is mentioned: "Flushing an istream is done using sync(). This cannot always be done right. For some kinds of streams, we would have to reread characters...
4
2356
by: james.lawton | last post by:
Hi, I'm having a problem that I can't diagnose. I'm creating istreams of unknown types, and want to manage them on the stack, co I'm passing around ownership-holding pointers. Usually, I would...
22
9303
by: Peter | last post by:
I am using VS2008. I have a Windows Service application which creates Crystal Reports. This is a multi theaded application which can run several reports at one time. My problem - there is a...
0
7103
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7307
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7370
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7021
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5614
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3188
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3177
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
755
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
409
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.