memory management (vb.net and vb6)

C

Chad

hello,

i am losing memory each time i make this call to a C++
dll (I make frequent calls).

'in VB.Net
Declare Function grab Lib "grabber.dll" _
(ByRef lpBuf As Byte, ByVal lnum As Integer) As Integer

the C++ function is...
DllExport void __stdcall grab(BYTE *bf, long num)


in VB6 everything is ok, no memory leak.
I understand that memory management in VB6 is auto but it
is not
in .net.

What do I have to do in this case? GC.collect does not
help.
 
F

Fergus Cooney

Hi Chad,

It might be useful if you tell us what grab() does and show how you are
calling it.

Regards,
Fergus
 
C

Chad

Hello,

grab() grabs DV frames from the camcorder. the C++ is a
DirectShow samplegrabber.

'***
Public class apifunctions

declare.....

public sub grabAviFrames(Byref dvFrames() as byte, Byval
numframes as integer)

Grab(dvFrames(0), numframes)

end class
'***

'main form
dim avicommand as new apifunctions
avicommand.grab(a, b)

appreciate any help
 
F

Fergus Cooney

Hi Chad,

I was hoping for a bit more - the actual declarations, sizes, calls, etc -
not just illustrations. ;-)

Does your data exceed 85K ?
Does grab do any allocation or just use the buffer passed in?
Etc?

You might find it useful to read the following:

An excellent two part article about garbage collection:
http://msdn.microsoft.com/msdnmag/issues/1100/gci/

Insights below the hood. Arrays, Strings, Pointers and Memory.
http://www.codeproject.com/dotnet/arrays.asp
http://www.codeproject.com/dotnet/pointers.asp.
http://www.codeproject.com/dotnet/strings.asp

Regards,
Fergus

ps. In part 2 of the first article there's a link to Figure 1 which uses
JavaScript. It failed on my machine. If it fails for you too, the full link
is http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/figures.asp.
 
C

Chad

Hi Fergus,
I will definitely go thru those links... thanx..
btw, those are actual codes. i just left out the
unnecessary ones(just too big).
Does your data exceed 85K ?
yes, dvFrames is about 120000bytes.
Does grab do any allocation or just use the buffer
passed in?
grab only uses the buffer passed in.

I cut out the following from the help files under
interopservices and memory management (have you seen it?)
seems to give a clue on the problem I am facing)...
but I'm not sure what I have to do to free the memory.

'______________________________________________________
The interop marshaler always attempts to free memory
allocated
by unmanaged code. This behavior complies with COM memory
management
rules, but differs from the rules that govern native C++.

Confusion can arise if you anticipate native C++ behavior
(no memory freeing) when using platform invoke, which
automatically
frees memory for pointers. For example, calling the
following
unmanaged method from a C++ DLL does not automatically
free any memory.
 
F

Fergus Cooney

Hi Chad,

|| The interop marshaler always attempts to free memory
|| allocated by unmanaged code

That's why I was asking about what grab() did. As VB is providing the
memory then it is managed memory and is not an issue.

|| || avicommand.grab(a, b)
||
|| btw, those are actual codes.

Lol. 'a' ?, 'b' ?? I don't believe you'd use those names!! :)

|| dvFrames is about 120000bytes.

The under-the-hood articles about arrays and pointers mentions items
greater than 85K. It says:

<quote>
Large arrays can have a significant performance hit. Any large object that
consumes 85K is placed in the large object heap. Practically speaking, almost
all of these objects are going to be arrays, and possibly some strings,
because very few classes will contain enough fields to exceed that amount of
memory.

Large objects are not compacted, and are only removed in a FULL garbage
collection, containing generation 2. If the large object includes any
finalizers, then at least two FULL garbage collections will be required.

Since FULL garbage collections can be 100 times or more less frequent than
the partial collections, it can take a long time for memory to be recovered.

Thus, a very poor allocation scheme, probably the worst, for a .NET
application would be one that allocates large amounts very frequently for
temporary uses.
</quote>

Maybe this has something to do with it? Is it possible for you to reuse
the same array/arrays ?

Regards,
Fergus
 
T

Tom Shelton

Fergus said:
Hi Chad,

|| The interop marshaler always attempts to free memory
|| allocated by unmanaged code

That's why I was asking about what grab() did. As VB is providing the
memory then it is managed memory and is not an issue.

|| || avicommand.grab(a, b)
||
|| btw, those are actual codes.

Lol. 'a' ?, 'b' ?? I don't believe you'd use those names!! :)

|| dvFrames is about 120000bytes.

The under-the-hood articles about arrays and pointers mentions items
greater than 85K. It says:

<quote>
Large arrays can have a significant performance hit. Any large object
that
consumes 85K is placed in the large object heap. Practically speaking,
almost all of these objects are going to be arrays, and possibly some
strings, because very few classes will contain enough fields to exceed
that amount of memory.

Large objects are not compacted, and are only removed in a FULL
garbage
collection, containing generation 2. If the large object includes any
finalizers, then at least two FULL garbage collections will be required.

Since FULL garbage collections can be 100 times or more less frequent
than
the partial collections, it can take a long time for memory to be
recovered.

Thus, a very poor allocation scheme, probably the worst, for a .NET
application would be one that allocates large amounts very frequently for
temporary uses.
</quote>

Maybe this has something to do with it? Is it possible for you to
reuse
the same array/arrays ?

Regards,
Fergus

Not to mention that there was a bug in GC for the large object heap in V1.0.
If he isn't runing 1.1 it is quite possible that those objects will never
be gc'd at all :)

Tom Shelton
 
F

Fergus Cooney

Hi Tom,

That's interesting. I'm using v1.0 so I shall be aware.

Thanks. :)

Regards,
Fergus
 
J

Jay B. Harlow [MVP - Outlook]

Chad,
I hope you realize that your grab function only ever returns a single byte
to .NET!
'in VB.Net
Declare Function grab Lib "grabber.dll" _
(ByRef lpBuf As Byte, ByVal lnum As Integer) As Integer

You have ByRef as Byte, the way .NET works is a single byte will be copied
to lpBuf. Or worse you are modifing managed memory in unexpected ways which
is sure to cause engine execution exceptions.
I understand that memory management in VB6 is auto but it
is not in .net.
You understand incorrectly! Memory Management is automatic in .NET also.
What changed is finalization (terminate event) is now non-deterministic.

Which means memory management still happens automatically, Finalization (the
"terminate event") just happens at the will of the garbage collector.

Normal C++ memory management is not auto as you need to match each new with
a delete. There is no delete per se in .NET (Dispose is there to release
unmanaged resource it does not effect the memory itself).

You may want to ask this question 'down the hall' in the
microsoft.public.dotnet.framework.interop newsgroup.

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top