DotNetNewsgroup.com  
web access to complete list of Microsoft.NET newsgroups
   home   |   control panel login   |   archive  |  
 
  carried group
academic
adonet
aspnet
aspnet.announcements
aspnet.buildingcontrols
aspnet.caching
aspnet.datagridcontrol
aspnet.mobile
aspnet.security
aspnet.webcontrols
aspnet.webservices
assignment_manager
datatools
dotnet.distributed_apps
dotnet.general
dotnet.myservices
dotnet.nternationalization
dotnet.scripting
dotnet.security
dotnet.vjsharp
dotnet.vsa
dotnet.xml
dotnetfaqs
framework
framework.clr
framework.compactframework
framework.component_services
framework.controls
framework.databinding
framework.drawing
framework.enhancements
framework.interop
framework.odbcnet
framework.performance
framework.remoting
framework.sdk
framework.setup
framework.webservices
framework.windowsforms
framework.wmi
frwk.windowsforms.designtime
lang.csharp
lang.jscript
lang.vb
lang.vb.controls
lang.vb.data
lang.vb.upgrade
lang.vc
lang.vc.libraries
  
 
start date: Thu, 12 Jul 2007 14:38:58 -0700,    posted on: microsoft.public.dotnet.framework.interop        back       

Thread Index
  1    unknown
          2    Michael Phillips, Jr. 0.c0m
          3    unknown
          4    Willy Denoyette [MVP]


Marshal.PtrToStringAnsi() Memory Leak?   
I've been noticing a memory leak with the following sample code
snippet. Can someone please advise.

Have a C# Winforms app with the following code on a button-click
event.

private void button1_Click(object sender, System.EventArgs e)
{
	IntPtr p1 = new IntPtr(-1);
	string inputStr;
	AllocString(out p1); //AllocString() called via Interop
	string managedStr = Marshal.PtrToStringAnsi(p1);
	Thread.Sleep(20);
	Marshal.FreeHGlobal(p1);

}

The method AllocString() is defined in a C-DLL as:
CDLL_API void AllocString(char** inputStr)
{
	int len = 10000000;
	char * x = (char *) GlobalAlloc(0, len+1);
	memset(x,65,len);
	x[l]=0;
	*inputStr = x;
}

On launching the application, the steady state private bytes is 10MB.

On clicking the button, I see private bytes increase by 30MB. Why the
additional overhead of 20MB for PtrToStringAnsi()? And this 20MB is
never freed. Also confirmed that the bytes allocated are in the
unmanaged code, since the .NET "# Bytes in All Heaps" never increases.

If I comment the Marshal.PtrToStringAnsi() line, private bytes always
comes back to 10MB.

Is this expected behavior for Marshal.PtrToStringAnsi() ? (.NET
Framework 1.1)
Date:Thu, 12 Jul 2007 14:38:58 -0700   Author:  

Re: Marshal.PtrToStringAnsi() Memory Leak?   

> Is this expected behavior for Marshal.PtrToStringAnsi() ? (.NET
> Framework 1.1)


It looks like the expected behavior.

Per the MSDN documentation, PtrToStringAnsi allocates a managed ANSI string 
and widens it to UNICODE when it copies your unmanaged string.

Your code allocates an unmanaged string of 10,000,000 bytes which is copied 
to a managed string of 20,000,000 bytes.

A managed string's memory exists until it is garbage collected.


 wrote in message 
news:1184276338.850234.219780@o61g2000hsh.googlegroups.com...

> I've been noticing a memory leak with the following sample code
> snippet. Can someone please advise.
>
> Have a C# Winforms app with the following code on a button-click
> event.
>
> private void button1_Click(object sender, System.EventArgs e)
> {
> IntPtr p1 = new IntPtr(-1);
> string inputStr;
> AllocString(out p1); //AllocString() called via Interop
> string managedStr = Marshal.PtrToStringAnsi(p1);
> Thread.Sleep(20);
> Marshal.FreeHGlobal(p1);
>
> }
>
> The method AllocString() is defined in a C-DLL as:
> CDLL_API void AllocString(char** inputStr)
> {
> int len = 10000000;
> char * x = (char *) GlobalAlloc(0, len+1);
> memset(x,65,len);
> x[l]=0;
> *inputStr = x;
> }
>
> On launching the application, the steady state private bytes is 10MB.
>
> On clicking the button, I see private bytes increase by 30MB. Why the
> additional overhead of 20MB for PtrToStringAnsi()? And this 20MB is
> never freed. Also confirmed that the bytes allocated are in the
> unmanaged code, since the .NET "# Bytes in All Heaps" never increases.
>
> If I comment the Marshal.PtrToStringAnsi() line, private bytes always
> comes back to 10MB.
>
> Is this expected behavior for Marshal.PtrToStringAnsi() ? (.NET
> Framework 1.1)
> 
Date:Thu, 12 Jul 2007 19:55:05 -0400   Author:  

Re: Marshal.PtrToStringAnsi() Memory Leak?   

> It looks like the expected behavior.
>
> Per the MSDN documentation, PtrToStringAnsi allocates a managed ANSI string
> and widens it to UNICODE when it copies your unmanaged string.
>
> Your code allocates an unmanaged string of 10,000,000 bytes which is copied
> to a managed string of 20,000,000 bytes.
>
> A managed string's memory exists until it is garbage collected.


Interesting. If its copying over to a "managed" string of 20MB, I
would expect the Perfmon .NET "# Bytes in All Heaps" counter to
increase by 20MB. (Since its allocating on the managed heap). But,
this counter does not change.
Instead, the "Private Bytes" counter is increasing by 20MB.

Also, tried GC.Collect but doesn't seem to drop the Private Bytes..
which seem to imply the memory is allocated on the unmanaged heap?
Date:Thu, 12 Jul 2007 17:33:03 -0700   Author:  

Re: Marshal.PtrToStringAnsi() Memory Leak?   
wrote in message 
news:1184276338.850234.219780@o61g2000hsh.googlegroups.com...

> I've been noticing a memory leak with the following sample code
> snippet. Can someone please advise.
>
> Have a C# Winforms app with the following code on a button-click
> event.
>
> private void button1_Click(object sender, System.EventArgs e)
> {
> IntPtr p1 = new IntPtr(-1);
> string inputStr;
> AllocString(out p1); //AllocString() called via Interop
> string managedStr = Marshal.PtrToStringAnsi(p1);
> Thread.Sleep(20);
> Marshal.FreeHGlobal(p1);
>
> }
>
> The method AllocString() is defined in a C-DLL as:
> CDLL_API void AllocString(char** inputStr)
> {
> int len = 10000000;
> char * x = (char *) GlobalAlloc(0, len+1);
> memset(x,65,len);
> x[l]=0;
> *inputStr = x;
> }
>
> On launching the application, the steady state private bytes is 10MB.
>
> On clicking the button, I see private bytes increase by 30MB. Why the
> additional overhead of 20MB for PtrToStringAnsi()? And this 20MB is
> never freed. Also confirmed that the bytes allocated are in the
> unmanaged code, since the .NET "# Bytes in All Heaps" never increases.
>
> If I comment the Marshal.PtrToStringAnsi() line, private bytes always
> comes back to 10MB.
>
> Is this expected behavior for Marshal.PtrToStringAnsi() ? (.NET
> Framework 1.1)
>



The memory allocated by GlobalAlloc (or LocalAlloc) is not returned to the 
OS after freeing, it is kept in the process space for successive use. This 
memory will be reclaimed by the OS when there is memory pressure.
 Note also, that your code has a *bug* in the sense that you are allocating 
using "GlobalAlloc" and de-allocating using "LocalFree" (implicitely called 
by FreeHGlobal). LocalFree must be paired with LocalAlloc.
Date:Fri, 13 Jul 2007 14:51:54 +0200   Author:  

Google
 
Web dotnetnewsgroup.com


COPYRIGHT ?2005, EUROFRONT WORLDWIDE LTD., ALL RIGHT RESERVE  |   Contact us