Saturday, March 31, 2012

Sharing DLL between threads

Hi:
I've a third party DLL (not a .NET class library PE) which I use using
DllImport attribute in my application running in multiple threads invoking
different methods of the same DLL.
The memory usage of the application is shooting to 1GB in just 30 minutes.
It goes till it's 1.4GB after which I get OutOfMEmory exceptions. If I don't
use the DLL, my memory stays put at 100MB.
I tried freeing the DLL using FreeLibrary but after few seconds I am getting
"Object reference not set to an instance of an object" while accessing the
methods of the DLL.
How can I ensure that only one copy of the DLL per thread is in my
application memory and that the DLL is unloaded when it's no longer used by
any of the threads?
BTW, my application is an ASP.NET web service but this has nothing to do
with the statelessness of a webmethod because I am spawning and running the
threads in the background at application level.
Thanks,
Ramif you use standart PInvokde mechanism: DON'T EVER FREE your LIBRARY
amd it can't be unloaded.
but don't wory, there is, already, one single instance of the DLL in memory
for all thread (of all process!!!)
if you memory goes that up, it's very likely to be a bug in your application
DLL used with standart mechanism won't upload and DON'T EVER call a function
in a FREED Library.
That will crash your program instantly or, worst, cause weird, mysterious,
alien bugs...
On the other hand, with .NET 2.0 you could transform IntPtr (of a function
pointer) to a delegate.
So you could used LoadLibrary/FreeLibrary & GetProcAddress.
But even then, NEVER call into a FREED library.
"Ram P. Dash" <rampr2@.hotmail.com> wrote in message
news:oCvle.1050$MI4.716@.newsread2.news.pas.earthlink.net...
> Hi:
> I've a third party DLL (not a .NET class library PE) which I use using
> DllImport attribute in my application running in multiple threads invoking
> different methods of the same DLL.
> The memory usage of the application is shooting to 1GB in just 30 minutes.
> It goes till it's 1.4GB after which I get OutOfMEmory exceptions. If I
> don't use the DLL, my memory stays put at 100MB.
> I tried freeing the DLL using FreeLibrary but after few seconds I am
> getting "Object reference not set to an instance of an object" while
> accessing the methods of the DLL.
> How can I ensure that only one copy of the DLL per thread is in my
> application memory and that the DLL is unloaded when it's no longer used
> by any of the threads?
> BTW, my application is an ASP.NET web service but this has nothing to do
> with the statelessness of a webmethod because I am spawning and running
> the threads in the background at application level.
> Thanks,
> Ram
>
Thanks,
However when I looked at the ProcessModuleCollection somewhere in my code, I
saw the same DLL appear three times in the collection my test environment
(where close to 5 threads run at a time). Doesn't that tell that three
copies of the same DLL is in my application memory?
Thanks,
Ram
"Lloyd Dupont" <net.galador@.ld> wrote in message
news:uh8fbgmYFHA.2380@.tk2msftngp13.phx.gbl...
> if you use standart PInvokde mechanism: DON'T EVER FREE your LIBRARY
> amd it can't be unloaded.
> but don't wory, there is, already, one single instance of the DLL in
memory
> for all thread (of all process!!!)
> if you memory goes that up, it's very likely to be a bug in your
application
> DLL used with standart mechanism won't upload and DON'T EVER call a
function
> in a FREED Library.
> That will crash your program instantly or, worst, cause weird, mysterious,
> alien bugs...
>
> On the other hand, with .NET 2.0 you could transform IntPtr (of a function
> pointer) to a delegate.
> So you could used LoadLibrary/FreeLibrary & GetProcAddress.
> But even then, NEVER call into a FREED library.
>
> "Ram P. Dash" <rampr2@.hotmail.com> wrote in message
> news:oCvle.1050$MI4.716@.newsread2.news.pas.earthlink.net...
invoking
minutes.
>
mmh... you makes me wonder.
I haven't used this window much so I'm not sure, but do you have an address
for the DLL, I'll bet, it's the same address everytime.
Theoritically DLL are loaded once and there is a system wide counter
incremented every time they are used and decremented evrytime they are
freed.
normally, all what a process could do is increment this counter.
it's one of the major concept of the DLL, so I kind of doubt XP bug on
this...
"Ram P. Dash" <rampr2@.hotmail.com> wrote in message
news:uoD7Q3sYFHA.3356@.TK2MSFTNGP15.phx.gbl...
> Thanks,
> However when I looked at the ProcessModuleCollection somewhere in my code,
> I
> saw the same DLL appear three times in the collection my test environment
> (where close to 5 threads run at a time). Doesn't that tell that three
> copies of the same DLL is in my application memory?
> Thanks,
> Ram
> "Lloyd Dupont" <net.galador@.ld> wrote in message
> news:uh8fbgmYFHA.2380@.tk2msftngp13.phx.gbl...
> memory
> application
> function
> invoking
> minutes.
>
1) What sort of a dll is this? If a C++ or similar, are you sure it releases
it's memory properly after use?
I had such a problem a while ago... forgot to clean up the c++ dll from my
C# interop wrapper. When you describe your memory leaks, this is the type of
problem I would put my money on.
2) I'm not entirely sure you can freely multithread anything you may want
to. Are you sure the component is thread safe and that the results you're
getting back are ok?
3) In general you could wrap your dll into a managed wrapper that runs as an
EnterpriseServices (COM+) server.
This way it runs out-of process of the main application, you can pool the
objects, and you get object lifetime & recycling control (you can set the
memory limits; e.g. if the mem usage of the object reaches xx megs, kill it,
and use a freshly instantiated object with next call; or put a number of
calls limit on it - the object gets recycled every xx calls).
This is the way to go when you have rogue unmanaged third-party dlls that
don't work quite properly. Sure, you lose some performance, but gain a lot
of stability.
Win Xp or w2k3 are recommended, though, as they use COM+ 1.5 which offers
more features.
Regards,
Sigmund Jakhel
"Ram P. Dash" <rampr2@.hotmail.com> wrote in message
news:oCvle.1050$MI4.716@.newsread2.news.pas.earthlink.net...
> Hi:
> I've a third party DLL (not a .NET class library PE) which I use using
> DllImport attribute in my application running in multiple threads invoking
> different methods of the same DLL.
> The memory usage of the application is shooting to 1GB in just 30 minutes.
> It goes till it's 1.4GB after which I get OutOfMEmory exceptions. If I
> don't use the DLL, my memory stays put at 100MB.
> I tried freeing the DLL using FreeLibrary but after few seconds I am
> getting "Object reference not set to an instance of an object" while
> accessing the methods of the DLL.
> How can I ensure that only one copy of the DLL per thread is in my
> application memory and that the DLL is unloaded when it's no longer used
> by any of the threads?
> BTW, my application is an ASP.NET web service but this has nothing to do
> with the statelessness of a webmethod because I am spawning and running
> the threads in the background at application level.
> Thanks,
> Ram
>

0 comments:

Post a Comment