Memory Leak during p/invoke or fragmentation?

L

Lcubed

I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.

Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.

Here's some typical problem area code boiled down :

[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);

[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}

unsafe static public bool UseGetMyData()
{
int sz = 0;

try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}

unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}


// some C++ code for MyDLL

typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;


static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);


bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}

int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
P

Paul G. Tobey [eMVP]

I would guess that the DLL that's being invoked is still loaded. You might
add some logging to your DLL that will mark in the log when it's a) loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL was
unloaded after the invoke operation or if it's still in memory.

Paul T.
 
L

Lcubed

Doh! Thanks Paul! That's it!

I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.

I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?

Thanks again for your help!
Lcubed

I would guess that the DLL that's being invoked is still loaded.  You might
add some logging to your DLL that will mark in the log when it's a) loaded,
b) unloaded.  After you P/Invoke it, check the log and see if the DLL was
unloaded after the invoke operation or if it's still in memory.

Paul T.


I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
   public Int16 MyInt;
   public bool  MyBool;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
   int sz = 0;
   try
   {
       DATASTRUCT p = new DATASTRUCT();
       if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
       {
   // Data from DATASTRUCT p used or
   // assigned to other variables here
       }
       else return false;
   }
   catch (Exception ex)
   {
        // error handling here
       return false;
   }
}
unsafe static public bool UseSetMyData()
{
   try
   {
       DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
       return SetMyData(ref p);
   }
   catch (Exception ex)
   {
        // error handling here
       return false;
   }
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool    MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int  GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
C

Chris Tacke, eMVP

Depends on the data. When a managed app calls a P/Invoke, it loads the DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Doh! Thanks Paul! That's it!

I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.

I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?

Thanks again for your help!
Lcubed

I would guess that the DLL that's being invoked is still loaded. You might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL was
unloaded after the invoke operation or if it's still in memory.

Paul T.


I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
P

Paul G. Tobey [eMVP]

I have no idea how to load/unload in managed code, other than by P/Invoking
LoadLibrary() and FreeLibrary(), just as you would in C, and using
GetProcAddress() to get a function pointer through which you'd call your
functions. I don't think that having the managed run-time unload the DLL
after every function call would work, in general. Imagine, just to choose
an example, WinSock. When you call WSAStartup(), it assumes that the DLL is
going to be around while you make calls to send(), recv(), connect(),
listen(), etc. Causing the DLL to unload after calling WSAStartup would
mean that nothing would work.

Maybe someone else knows more about the internal workings of the run-time...

Paul T.

Doh! Thanks Paul! That's it!

I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.

I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?

Thanks again for your help!
Lcubed

I would guess that the DLL that's being invoked is still loaded. You might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL was
unloaded after the invoke operation or if it's still in memory.

Paul T.


I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
L

Lcubed

THanks Paul and Chris!

Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

L

Depends on the data.  When a managed app calls a P/Invoke, it loads theDLL
and it is not unloaded until your app ends.  Any static data in the DLL
remains allocated for that entire life.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com


Doh! Thanks Paul! That's it!

I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.

I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?

Thanks again for your help!
Lcubed

I would guess that the DLL that's being invoked is still loaded. You might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL was
unloaded after the invoke operation or if it's still in memory.
news:1f773d40-1233-4547-bce2-19d5f8d32113@n10g2000vbl.googlegroups.com....
I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
C

Chris Tacke, eMVP

Depends on your definition of "released" and the data. It's subject to
normal collection rules.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

THanks Paul and Chris!

Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

L

Depends on the data. When a managed app calls a P/Invoke, it loads the DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com


Doh! Thanks Paul! That's it!

I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.

I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?

Thanks again for your help!
Lcubed

I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL was
unloaded after the invoke operation or if it's still in memory.
news:1f773d40-1233-4547-bce2-19d5f8d32113@n10g2000vbl.googlegroups.com...
I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
P

Paul G. Tobey [eMVP]

The data is under the control of your program. You allocated it; you
release it. Having some parameter that is the address of the data passed to
a P/Invoked function does *nothing* to lock the memory or the object. Nor
does a return from the function "release" anything. It works just like
calling the function from C...

Paul T.

THanks Paul and Chris!

Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

L

Depends on the data. When a managed app calls a P/Invoke, it loads the DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com


Doh! Thanks Paul! That's it!

I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.

I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?

Thanks again for your help!
Lcubed

I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL was
unloaded after the invoke operation or if it's still in memory.
news:1f773d40-1233-4547-bce2-19d5f8d32113@n10g2000vbl.googlegroups.com...
I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
L

Lcubed

By the data, I mean the structures that I define in my C# code,
DATASTRUCT p = new DATASTRUCT(); , and pass the references to the DLL.
In my example, I'd say that "p" was the data. The memory for "p" is
allocated but not released.

By released, I meant memory that the GC will make available sooner or
later. My data is not being released, I added the debug code in :
GC.Collect(); // DEBUG
long totalmem = GC.GetTotalMemory(true); // DEBUG
to force the GC to make the memory available. It does not do so. I
have ran the program until the memory fills up (this takes awhile) and
the programs locks rather than just release the excess memory. As the
program may be required to run for several days, this is a bit
disturbing.

L


Depends on your definition of "released" and the data.  It's subject to
normal collection rules.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com


THanks Paul and Chris!

Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

L

Depends on the data. When a managed app calls a P/Invoke, it loads the DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com
"Lcubed" <[email protected]> wrote in message
Doh! Thanks Paul! That's it!
I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.
I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?
Thanks again for your help!
Lcubed
On Jan 12, 11:03 am, "Paul G. Tobey [eMVP]" <p space tobey no spam AT
no instrument no spam DOT com> wrote:
I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL was
unloaded after the invoke operation or if it's still in memory.
Paul T.

I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks..
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
L

Lcubed

Hi Paul, Chris,

Thanks for your patience, I've been researching a bit more. There's a
couple things that I'm not understanding.

In C#, accord to the language specification: "The memory occupied by
an object is automatically reclaimed when the object is no longer in
use. It is neither necessary nor possible to explicitly deallocate
objects in C#."

Again from the C# language spec: "Struct constructors are invoked with
the new operator, but that does not imply that memory is being
allocated. Instead of dynamically allocating an object and returning a
reference to it, a struct constructor simply returns the struct value
itself (typically in a temporary location on the stack), and this
value is then copied as necessary."

From my above example : DATASTRUCT p = new DATASTRUCT();
If I didn't just allocate memory for that, then how come my memory
usage increased?
If I did, then how do I deallocate it in C# ?
It was my understanding that it would be deallocated when the object
was no longer in use. If the GC does not realize that the object is no
longer in use, how can I help it along?

L

The data is under the control of your program.  You allocated it; you
release it.  Having some parameter that is the address of the data passed to
a P/Invoked function does *nothing* to lock the memory or the object.  Nor
does a return from the function "release" anything.  It works just like
calling the function from C...

Paul T.


THanks Paul and Chris!

Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

L

Depends on the data. When a managed app calls a P/Invoke, it loads the DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com
"Lcubed" <[email protected]> wrote in message
Doh! Thanks Paul! That's it!
I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.
I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?
Thanks again for your help!
Lcubed
On Jan 12, 11:03 am, "Paul G. Tobey [eMVP]" <p space tobey no spam AT
no instrument no spam DOT com> wrote:
I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL was
unloaded after the invoke operation or if it's still in memory.
Paul T.

I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks..
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
P

Paul G. Tobey [eMVP]

If you do 'new <whatever>', you've allocated memory for it in the heap.
There is no equivalent of 'delete' from C++ or 'free' from C in C#. The
allocation is garbage-collected, so the run-time will figure out when you
have no more references to the memory and will release it when it decides
that.

However, that's not the same as saying that as soon as you lose the last
reference, the memory will be recovered. Nothing that you referenced there
indicates that and that's not what happens. A garbage collection cycle will
be fired at various different times during execution of the program. If an
allocation is requested (you call 'new'), and there's not enough memory to
do the allocation, that will force memory to be collected in hopes that the
allocation will succeed. Otherwise, when garbage is collected is
indeterminate (you can force it, but that's a bad idea). This is just the
way things are in garbage collected systems; you don't control when things
are freed, generally.

Paul T.

Hi Paul, Chris,

Thanks for your patience, I've been researching a bit more. There's a
couple things that I'm not understanding.

In C#, accord to the language specification: "The memory occupied by
an object is automatically reclaimed when the object is no longer in
use. It is neither necessary nor possible to explicitly deallocate
objects in C#."

Again from the C# language spec: "Struct constructors are invoked with
the new operator, but that does not imply that memory is being
allocated. Instead of dynamically allocating an object and returning a
reference to it, a struct constructor simply returns the struct value
itself (typically in a temporary location on the stack), and this
value is then copied as necessary."

From my above example : DATASTRUCT p = new DATASTRUCT();
If I didn't just allocate memory for that, then how come my memory
usage increased?
If I did, then how do I deallocate it in C# ?
It was my understanding that it would be deallocated when the object
was no longer in use. If the GC does not realize that the object is no
longer in use, how can I help it along?

L

The data is under the control of your program. You allocated it; you
release it. Having some parameter that is the address of the data passed
to
a P/Invoked function does *nothing* to lock the memory or the object. Nor
does a return from the function "release" anything. It works just like
calling the function from C...

Paul T.


THanks Paul and Chris!

Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

L

Depends on the data. When a managed app calls a P/Invoke, it loads the
DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com
"Lcubed" <[email protected]> wrote in message
Doh! Thanks Paul! That's it!
I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.
I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?
Thanks again for your help!
Lcubed
On Jan 12, 11:03 am, "Paul G. Tobey [eMVP]" <p space tobey no spam AT
no instrument no spam DOT com> wrote:
I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL
was
unloaded after the invoke operation or if it's still in memory.
Paul T.

I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
L

Lcubed

Thanks Paul,

I guess that tells me that my memory leak isn't where I thought it
was.

L

If you do 'new <whatever>', you've allocated memory for it in the heap.
There is no equivalent of 'delete' from C++ or 'free' from C in C#.  The
allocation is garbage-collected, so the run-time will figure out when you
have no more references to the memory and will release it when it decides
that.

However, that's not the same as saying that as soon as you lose the last
reference, the memory will be recovered.  Nothing that you referenced there
indicates that and that's not what happens.  A garbage collection cyclewill
be fired at various different times during execution of the program.  If an
allocation is requested (you call 'new'), and there's not enough memory to
do the allocation, that will force memory to be collected in hopes that the
allocation will succeed.  Otherwise, when garbage is collected is
indeterminate (you can force it, but that's a bad idea).  This is just the
way things are in garbage collected systems; you don't control when things
are freed, generally.

Paul T.


Hi Paul, Chris,

Thanks for your patience, I've been researching a bit more. There's a
couple things that I'm not understanding.

In C#, accord to the language specification: "The memory occupied by
an object is automatically reclaimed when the object is no longer in
use. It is neither necessary nor possible to explicitly deallocate
objects in C#."

Again from the C# language spec: "Struct constructors are invoked with
the new operator, but that does not imply that memory is being
allocated. Instead of dynamically allocating an object and returning a
reference to it, a struct constructor simply returns the struct value
itself (typically in a temporary location on the stack), and this
value is then copied as necessary."

From my above example : DATASTRUCT p = new DATASTRUCT();
If I didn't just allocate memory for that, then how come my memory
usage increased?
If I did, then how do I deallocate it in C# ?
It was my understanding that it would be deallocated when the object
was no longer in use. If the GC does not realize that the object is no
longer in use, how can I help it along?

L

The data is under the control of your program. You allocated it; you
release it. Having some parameter that is the address of the data passed
to
a P/Invoked function does *nothing* to lock the memory or the object. Nor
does a return from the function "release" anything. It works just like
calling the function from C...
"Lcubed" <[email protected]> wrote in message
THanks Paul and Chris!
Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

On Jan 12, 12:15 pm, "Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com>
wrote:
Depends on the data. When a managed app calls a P/Invoke, it loads the
DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.
--
Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com
Doh! Thanks Paul! That's it!
I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.
I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?
Thanks again for your help!
Lcubed
On Jan 12, 11:03 am, "Paul G. Tobey [eMVP]" <p space tobey no spam AT
no instrument no spam DOT com> wrote:
I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL
was
unloaded after the invoke operation or if it's still in memory.
Paul T.

I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
C

Chris Tacke, eMVP

As a point to consider, GC.Collect does *not* release memory to the system.
Doesn't explain the lockup, but it's important.

With your small repro you can get a lockup? I've certainly not seeing it
(looking at the code).


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com




By the data, I mean the structures that I define in my C# code,
DATASTRUCT p = new DATASTRUCT(); , and pass the references to the DLL.
In my example, I'd say that "p" was the data. The memory for "p" is
allocated but not released.

By released, I meant memory that the GC will make available sooner or
later. My data is not being released, I added the debug code in :
GC.Collect(); // DEBUG
long totalmem = GC.GetTotalMemory(true); // DEBUG
to force the GC to make the memory available. It does not do so. I
have ran the program until the memory fills up (this takes awhile) and
the programs locks rather than just release the excess memory. As the
program may be required to run for several days, this is a bit
disturbing.

L


Depends on your definition of "released" and the data. It's subject to
normal collection rules.

--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com


THanks Paul and Chris!

Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

L

Depends on the data. When a managed app calls a P/Invoke, it loads the
DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com
"Lcubed" <[email protected]> wrote in message
Doh! Thanks Paul! That's it!
I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.
I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?
Thanks again for your help!
Lcubed
On Jan 12, 11:03 am, "Paul G. Tobey [eMVP]" <p space tobey no spam AT
no instrument no spam DOT com> wrote:
I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL
was
unloaded after the invoke operation or if it's still in memory.
Paul T.

I found a memory leak in my application and fixed a few minor things
after reading all the helpful posts and information on memory leaks.
However, there's still one left. Every time I p/invoke code from my
dll, tiny bits of memory (under 100 bytes) are not reclaimed. While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
C

Chris Tacke, eMVP

Correct, I don't see any leak in the code you posted.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com

Thanks Paul,

I guess that tells me that my memory leak isn't where I thought it
was.

L

If you do 'new <whatever>', you've allocated memory for it in the heap.
There is no equivalent of 'delete' from C++ or 'free' from C in C#. The
allocation is garbage-collected, so the run-time will figure out when you
have no more references to the memory and will release it when it decides
that.

However, that's not the same as saying that as soon as you lose the last
reference, the memory will be recovered. Nothing that you referenced there
indicates that and that's not what happens. A garbage collection cycle
will
be fired at various different times during execution of the program. If an
allocation is requested (you call 'new'), and there's not enough memory to
do the allocation, that will force memory to be collected in hopes that
the
allocation will succeed. Otherwise, when garbage is collected is
indeterminate (you can force it, but that's a bad idea). This is just the
way things are in garbage collected systems; you don't control when things
are freed, generally.

Paul T.


Hi Paul, Chris,

Thanks for your patience, I've been researching a bit more. There's a
couple things that I'm not understanding.

In C#, accord to the language specification: "The memory occupied by
an object is automatically reclaimed when the object is no longer in
use. It is neither necessary nor possible to explicitly deallocate
objects in C#."

Again from the C# language spec: "Struct constructors are invoked with
the new operator, but that does not imply that memory is being
allocated. Instead of dynamically allocating an object and returning a
reference to it, a struct constructor simply returns the struct value
itself (typically in a temporary location on the stack), and this
value is then copied as necessary."

From my above example : DATASTRUCT p = new DATASTRUCT();
If I didn't just allocate memory for that, then how come my memory
usage increased?
If I did, then how do I deallocate it in C# ?
It was my understanding that it would be deallocated when the object
was no longer in use. If the GC does not realize that the object is no
longer in use, how can I help it along?

L

The data is under the control of your program. You allocated it; you
release it. Having some parameter that is the address of the data passed
to
a P/Invoked function does *nothing* to lock the memory or the object.
Nor
does a return from the function "release" anything. It works just like
calling the function from C...
"Lcubed" <[email protected]> wrote in message
THanks Paul and Chris!
Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

On Jan 12, 12:15 pm, "Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com>
wrote:
Depends on the data. When a managed app calls a P/Invoke, it loads the
DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.
--
Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com
Doh! Thanks Paul! That's it!
I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.
I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?
Thanks again for your help!
Lcubed
On Jan 12, 11:03 am, "Paul G. Tobey [eMVP]" <p space tobey no spam AT
no instrument no spam DOT com> wrote:
I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL
was
unloaded after the invoke operation or if it's still in memory.
Paul T.

I found a memory leak in my application and fixed a few minor
things
after reading all the helpful posts and information on memory
leaks.
However, there's still one left. Every time I p/invoke code from
my
dll, tiny bits of memory (under 100 bytes) are not reclaimed.
While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
P

Paul G. Tobey [eMVP]

Memory used will usually continue to grow until something triggers a
collection operation. You can't look at the total memory allocated by the
managed run-time and conclude anything about whether there is a leak or not.
It's just not the right information. You can use the .NET Compact Framework
3.5 Power Toys to get some real information about leaks, allocations, etc.
That should help you determine whether there's really a leak and, if so, who
is leaking...

Paul T.


Thanks Paul,

I guess that tells me that my memory leak isn't where I thought it
was.

L

If you do 'new <whatever>', you've allocated memory for it in the heap.
There is no equivalent of 'delete' from C++ or 'free' from C in C#. The
allocation is garbage-collected, so the run-time will figure out when you
have no more references to the memory and will release it when it decides
that.

However, that's not the same as saying that as soon as you lose the last
reference, the memory will be recovered. Nothing that you referenced there
indicates that and that's not what happens. A garbage collection cycle
will
be fired at various different times during execution of the program. If an
allocation is requested (you call 'new'), and there's not enough memory to
do the allocation, that will force memory to be collected in hopes that
the
allocation will succeed. Otherwise, when garbage is collected is
indeterminate (you can force it, but that's a bad idea). This is just the
way things are in garbage collected systems; you don't control when things
are freed, generally.

Paul T.


Hi Paul, Chris,

Thanks for your patience, I've been researching a bit more. There's a
couple things that I'm not understanding.

In C#, accord to the language specification: "The memory occupied by
an object is automatically reclaimed when the object is no longer in
use. It is neither necessary nor possible to explicitly deallocate
objects in C#."

Again from the C# language spec: "Struct constructors are invoked with
the new operator, but that does not imply that memory is being
allocated. Instead of dynamically allocating an object and returning a
reference to it, a struct constructor simply returns the struct value
itself (typically in a temporary location on the stack), and this
value is then copied as necessary."

From my above example : DATASTRUCT p = new DATASTRUCT();
If I didn't just allocate memory for that, then how come my memory
usage increased?
If I did, then how do I deallocate it in C# ?
It was my understanding that it would be deallocated when the object
was no longer in use. If the GC does not realize that the object is no
longer in use, how can I help it along?

L

The data is under the control of your program. You allocated it; you
release it. Having some parameter that is the address of the data passed
to
a P/Invoked function does *nothing* to lock the memory or the object.
Nor
does a return from the function "release" anything. It works just like
calling the function from C...
"Lcubed" <[email protected]> wrote in message
THanks Paul and Chris!
Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?

On Jan 12, 12:15 pm, "Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com>
wrote:
Depends on the data. When a managed app calls a P/Invoke, it loads the
DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.
--
Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com
Doh! Thanks Paul! That's it!
I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.
I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?
Thanks again for your help!
Lcubed
On Jan 12, 11:03 am, "Paul G. Tobey [eMVP]" <p space tobey no spam AT
no instrument no spam DOT com> wrote:
I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL
was
unloaded after the invoke operation or if it's still in memory.
Paul T.

I found a memory leak in my application and fixed a few minor
things
after reading all the helpful posts and information on memory
leaks.
However, there's still one left. Every time I p/invoke code from
my
dll, tiny bits of memory (under 100 bytes) are not reclaimed.
While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 
L

Lcubed

Thanks again Chris and Paul,

I made an app with only my repo (should've done that first) and no
errors there. So it's a custom control, or something else going on at
the same time. Thanks for the Power Toys suggestion!

L

Memory used will usually continue to grow until something triggers a
collection operation.  You can't look at the total memory allocated by the
managed run-time and conclude anything about whether there is a leak or not.
It's just not the right information.  You can use the .NET Compact Framework
3.5 Power Toys to get some real information about leaks, allocations, etc..
That should help you determine whether there's really a leak and, if so, who
is leaking...

Paul T.


Thanks Paul,

I guess that tells me that my memory leak isn't where I thought it
was.

L

If you do 'new <whatever>', you've allocated memory for it in the heap.
There is no equivalent of 'delete' from C++ or 'free' from C in C#. The
allocation is garbage-collected, so the run-time will figure out when you
have no more references to the memory and will release it when it decides
that.
However, that's not the same as saying that as soon as you lose the last
reference, the memory will be recovered. Nothing that you referenced there
indicates that and that's not what happens. A garbage collection cycle
will
be fired at various different times during execution of the program. Ifan
allocation is requested (you call 'new'), and there's not enough memoryto
do the allocation, that will force memory to be collected in hopes that
the
allocation will succeed. Otherwise, when garbage is collected is
indeterminate (you can force it, but that's a bad idea). This is just the
way things are in garbage collected systems; you don't control when things
are freed, generally.
"Lcubed" <[email protected]> wrote in message
Hi Paul, Chris,
Thanks for your patience, I've been researching a bit more. There's a
couple things that I'm not understanding.
In C#, accord to the language specification: "The memory occupied by
an object is automatically reclaimed when the object is no longer in
use. It is neither necessary nor possible to explicitly deallocate
objects in C#."
Again from the C# language spec: "Struct constructors are invoked with
the new operator, but that does not imply that memory is being
allocated. Instead of dynamically allocating an object and returning a
reference to it, a struct constructor simply returns the struct value
itself (typically in a temporary location on the stack), and this
value is then copied as necessary."
From my above example : DATASTRUCT p = new DATASTRUCT();
If I didn't just allocate memory for that, then how come my memory
usage increased?
If I did, then how do I deallocate it in C# ?
It was my understanding that it would be deallocated when the object
was no longer in use. If the GC does not realize that the object is no
longer in use, how can I help it along?

On Jan 12, 1:32 pm, "Paul G. Tobey [eMVP]" <p space tobey no spam AT
no instrument no spam DOT com> wrote:
The data is under the control of your program. You allocated it; you
release it. Having some parameter that is the address of the data passed
to
a P/Invoked function does *nothing* to lock the memory or the object.
Nor
does a return from the function "release" anything. It works just like
calling the function from C...
Paul T.
THanks Paul and Chris!
Chris, If the DLL stays loaded for the life of the app, that's great!
But... I need to find a way to dispose of the data. If I create it in
the C# app and pass it by reference to the DLL function, then the data
should be released when the C# function returns, right? If not, is
there a way I can release the memory without closing my application?
L
On Jan 12, 12:15 pm, "Chris Tacke, eMVP" <ctacke.at.opennetcf.dot.com>
wrote:
Depends on the data. When a managed app calls a P/Invoke, it loads the
DLL
and it is not unloaded until your app ends. Any static data in the DLL
remains allocated for that entire life.
--
Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded communityhttp://community.OpenNETCF.com
Doh! Thanks Paul! That's it!
I'm apologize if this is a stupid question, but I don't see the answer
on MSDN. Can you point me to a link or tell me how to load and unload
DLLs when I need to? My DLL also does some things in the background,
so there are times when it should stay loaded, but it stays in memory
when it is finished.
I thought in C#, that the memory for data created in a function was
released when the function returned. Is this not correct?
Thanks again for your help!
Lcubed
On Jan 12, 11:03 am, "Paul G. Tobey [eMVP]" <p space tobey no spam AT
no instrument no spam DOT com> wrote:
I would guess that the DLL that's being invoked is still loaded. You
might
add some logging to your DLL that will mark in the log when it's a)
loaded,
b) unloaded. After you P/Invoke it, check the log and see if the DLL
was
unloaded after the invoke operation or if it's still in memory.
Paul T.

I found a memory leak in my application and fixed a few minor
things
after reading all the helpful posts and information on memory
leaks.
However, there's still one left. Every time I p/invoke code from
my
dll, tiny bits of memory (under 100 bytes) are not reclaimed.
While
this does not seem like much, it would build up after a while.
Is there a chance it could be fragmentation? Does anyone have any
ideas? Any help or ideas appreciated.
Here's some typical problem area code boiled down :
[DllImport("MyDLL.dll", EntryPoint = "GetMyData", CharSet =
CharSet.Auto)]
unsafe static extern int GetMyData(ref DATASTRUCT data);
[DllImport("MyDLL.dll", EntryPoint = "SetMyData", CharSet =
CharSet.Auto)]
unsafe static extern bool SetMyData(ref DATASTRUCT data);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DATASTRUCT
{
public Int16 MyInt;
public bool MyBool;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string
MyString;
}
unsafe static public bool UseGetMyData()
{
int sz = 0;
try
{
DATASTRUCT p = new DATASTRUCT();
if ((sz = GetMyData(ref p)) == CORRECT_DATA_SIZE )
{
// Data from DATASTRUCT p used or
// assigned to other variables here
}
else return false;
}
catch (Exception ex)
{
// error handling here
return false;
}
}
unsafe static public bool UseSetMyData()
{
try
{
DATASTRUCT p = new DATASTRUCT();
// DATASTRUCT p variables assigned here
return SetMyData(ref p);
}
catch (Exception ex)
{
// error handling here
return false;
}
}
// some C++ code for MyDLL
typedef struct
{
__int16 MyInt;
bool MyBool;
wchar_t MyString[25];
} DATASTRUCT;
static _declspec(dllexport) int GetMyData(DATASTRUCT * data);
static _declspec(dllexport) bool SetMyData(DATASTRUCT * data);
bool SetMyData(DATASTRUCT * data)
{
// data used to set other variables here
return true;
}
int GetMyData(DATASTRUCT * data)
{
// data populated here
return sizeof(data);
}
 

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