Help Fixing a Memory Leak

T

TC

I need help fixing a memory leak. I've done a lot of research, but
most information is aimed at finding leaks, not at fixing them. I've
found the leak; I just don't know how to fix it.

In my project, I have a reference to a third-party .NET class library.
My application needs to create an instance of a class about every two
minutes, then discard it a short time later. I've found, however, that
each cycle causes my application to grow about 3 kb. The class does
not implement IDisposable, so I'm cleaning it up by setting the
variable = Nothing.

After the class is instantiated, I need to call a specific method
about 200 times. I've found that each time I call the method, my
application grows about 1 kb. This is a real killer. After a few days
of operation, I get an Out of Memory exception.

From my research, I've learned that the leak is affecting the
unmanaged memory heap. The problem is clearly in the third-party class
library. What can I do about it?


-TC
 
A

AMercer

My application needs to create an instance of a class about every two
minutes, then discard it a short time later. I've found, however, that
each cycle causes my application to grow about 3 kb.

Every two minutes, launch a process that creates the instance, does its
thing, and then when the process dies, the memory will be reclaimed. You
shouldn't have to do this kind of thing, but when stuck, you have to get
unstuck. You will likely face IPC issues, I hope not too many or too
complicated.
 
T

TC

Get the third-party component fixed.










- Show quoted text -

Stephany,

Thank you for the reply. Since fixing the third-party component is out
of the question, however, I was hoping to hear about other options.

One solution I'm considering is to create a completely separate
application to execute the 2-minute bit of functionality that relies
on the third-party component. That seems very inelegant, however.
Perhaps there is a way to do something equivalent with threads?

In doing research, I saw a comment which mentioned that "AppDomain
teardown", although extreme, was a way to recover leaked memory in the
unmanaged heap. What is "AppDomain teardown", and is there any way I
can use it to solve this memory leak problem?


-TC
 
C

Cor Ligthert[MVP]

TC,

Two answers in a question like way:

Does this so called "leak" cost you noticable performance or whatever

Are you using taskmanager to get this information, because this is a
known problem from taskmanager.

Cor
 
M

Michel Posseth [MCP]

TC


Maybe the class exposes a close , shutdown or whatever they called it method
, i have eaven once found a objRelease method in a third party component

Did you declare the class in method scope , or did you declare the class in
an encapsulated (wrapper ) wich you dispose off ? iff so the GC should have
kicked in

you might show us some code ( how you declarer and call the object )


michel
 
M

Michael C

TC said:
Thank you for the reply. Since fixing the third-party component is out
of the question, however, I was hoping to hear about other options.

Why is that out of the question? Send them a support request and complain a
lot and they should fix it.

Michael
 
C

cj

In a perfect world that might work but if TC's like me his first problem
is getting through to them, then having them acknowledge the problem,
then provided you do get them to actually admit it's a problem the fix
might take months. Sometimes it's best to just figure out how to work
with what you have.
 
H

Herfried K. Wagner [MVP]

Cor Ligthert said:
Two answers in a question like way:

Does this so called "leak" cost you noticable performance or whatever

The OP wrote:

| After a few days of operation, I get an Out of Memory exception.
 
C

Cor Ligthert[MVP]

Herfried,

You are right, can it be that the Op is using something as a recursiving
code as I like it so much and from what you forever wrote in past: If there
is enough memory that is not problem.

:)

(It is friday)

Cor
 
C

cj

I hate to say it but when I just HAVE to fix something I can do some
funny things. I had a leak that ran the machine out of memory but it
took about 14 - 18 days. I never could plug the leak and I too am sure
it was in a COM control I use. I have other things to do to so, I
finally set the app to restart the PC at 2:00am Friday mornings. That
has been probably a year ago now and I've had no problems with it since
then.
 
M

Michael C

cj said:
In a perfect world that might work but if TC's like me his first problem
is getting through to them, then having them acknowledge the problem, then
provided you do get them to actually admit it's a problem the fix might
take months. Sometimes it's best to just figure out how to work with what
you have.

Sounds like you're giving up before you even try. This is a MAJOR bug if
it's happening as you describe so you might be suprised at their response.
It's certainly something you have to do any way and anything else is just a
temporary solution until the real problem is fixed.

Michael
 
T

TC

Thanks for the advice. Several people asked for details, so here they
are:

- The leak does come at a cost. My application needs to run for weeks,
but I get an Out of Memory exception after ony a few days.

- Yes, I'm using Task Manager to monitor the memory. I know it isn't a
great tool for this purpose, but I'm watching it over a long period of
time (days), and it seems to be okay for that.

- I've looked for Close, Shutdown, Release, Dispose, and any other
method that may cleanup the class, but it just doesn't exist.

- I encapsulated the class in a wrapper, and I'm careful to dispose
the wrapper when I'm done. The memory leaks anyway.

- The reason it will be difficult to get the third-party component
fixed is that it isn't commercial software; it was written by
engineers in a distant branch of the company. They aren't accountable
for the performance of the software, and they aren't responsive to
requests for changes. I'm lucky to have what I've got. Nevertheless,
the point is well taken; I acknowledge that the ideal solution is to
fix their code.

I don't want to post my code because I'm not looking for specific
advice. I really just wanted to know if there was a standard solution
for the "What if a component leaks?" problem. From the replies I've
received, I conclude that there are three options: 1) get the
component fixed; 2) live with the leak; and 3) automatically shut down
and restart the application periodically (per CJ). In this case, I
think the best solution for me may be option 3.

Thanks again to everyone for the help.

-TC
 
M

Michael C

TC said:
I don't want to post my code because I'm not looking for specific
advice. I really just wanted to know if there was a standard solution
for the "What if a component leaks?" problem. From the replies I've
received, I conclude that there are three options: 1) get the
component fixed; 2) live with the leak; and 3) automatically shut down
and restart the application periodically (per CJ). In this case, I
think the best solution for me may be option 3.

A fourth solution was suggested which was to run the call to the component
via a seperate exe. Seeing that you call this once per 2 minutes, each 2
minutes you could fire up a seperate exe to make the calls for you. That was
your main app can keep running without needing to restart itself.

Michael
 
M

Michael C

cj said:
I hate to say it but when I just HAVE to fix something I can do some funny
things. I had a leak that ran the machine out of memory but it took about
14 - 18 days. I never could plug the leak and I too am sure it was in a
COM control I use. I have other things to do to so, I finally set the app
to restart the PC at 2:00am Friday mornings. That has been probably a year
ago now and I've had no problems with it since then.

Little dramatic don't you think? :)

Michael
 
C

cj

Yes the 4th option would work too. A master app to restart the troubled
app periodically. In my case folks here felt it was a good idea for the
pc to be rebooted too. But yes, at least in my case, the memory is
cleared up by shutting down and restarting just the leaky app so the 4th
option is good too.

For what it's worth in my app I have menu item to set the time of day
for the reboot to happen and you menu to check which days of the week to
reboot on. We figured the system should be the least busy at 2:00am so
we set it for then. I decided I wanted it to reboot on 2:00am of a day
I would be in at 8:00 in case it failed so selected Friday at 2:00am,
but it's all adjustable. The time and days selected are saved in a cfg
file with other program info. When the program starts or someone makes
adjustments to the reboot info it calculates when it will next reboot using.

Private Sub UpdateAutoReboot()
Dim testDate As Date
Dim tempStr As String

autoRebootActive = False
tempStr = "Auto Reboot Disabled"

For x As Int32 = 0 To 7
testDate =
Now.Date.AddDays(x).AddTicks(TimeValue(rebootTime).Ticks)
If testDate.DayOfWeek = DayOfWeek.Sunday And
SunMenuItem.Checked Or _
testDate.DayOfWeek = DayOfWeek.Monday And
MonMenuItem.Checked Or _
testDate.DayOfWeek = DayOfWeek.Tuesday And
TueMenuItem.Checked Or _
testDate.DayOfWeek = DayOfWeek.Wednesday And
WedMenuItem.Checked Or _
testDate.DayOfWeek = DayOfWeek.Thursday And
ThuMenuItem.Checked Or _
testDate.DayOfWeek = DayOfWeek.Friday And
FriMenuItem.Checked Or _
testDate.DayOfWeek = DayOfWeek.Saturday And
SatMenuItem.Checked Then

If testDate > Now Then 'if x=0 (today) it might be too
late in the day
autoRebootActive = True
nextReboot = testDate
tempStr = "Next Reboot" & vbCrLf & testDate.ToString
Exit For
End If
End If
Next

Label5.Text = tempStr
End Sub

A timer used in the program among other things checks to see if it's
time to reboot. If so it sets a flag and closes the program.

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick
If autoRebootActive And Now() >= nextReboot Then
rebootNow = True
Me.Close()
End If
End Sub

During closing the program if the flag is set to reboot it will do so.

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As
System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Timer1.Enabled = False
If rebootNow = True Then
Dim WMIService, Computer As Object
WMIService =
GetObject("Winmgmts:{impersonationLevel=impersonate,(Debug,Shutdown)}")
For Each Computer In
WMIService.InstancesOf("Win32_OperatingSystem")
Computer.Win32Shutdown(2 + 4, 0) 'reboot
Next
End If
End Sub

Remember to have the pc automatically start your program when it starts.
 
C

cj

Sometimes I get tired of playing around, so I bring out the sledge
hammer and move on. You know the old saying, if it doesn't fit you need
a bigger hammer. :) If only I could remember where I laid that hammer.
I have a Linux box that needs persuading to allow me to login via FTP
using root. I think it knows it's history once I pull those files off
it. ;)
 
M

Michael C

cj said:
Sometimes I get tired of playing around, so I bring out the sledge hammer
and move on. You know the old saying, if it doesn't fit you need a bigger
hammer. :) If only I could remember where I laid that hammer. I have a
Linux box that needs persuading to allow me to login via FTP using root.
I think it knows it's history once I pull those files off it. ;)

Fair enough :) I guess you've got to do whatever gives you the greatest
reliability and running an MS OS a weekly reboot might stop a lot of issues.
(how many times are server issues solved by a reboot :).

Michael
 
M

Michel Posseth [MCP]

After rereading this thread to see if the issue is solved , as the subject
interests me , and thus getting more information about your problem
i have another option. :)


you told in the thread that fixing the component by the third party is
probably not an option, you also describe that the solution is made inhouse
by another department , this is getting interesting cause in that case you
might have the option to rewrite the component yourself ( no issues with
copyright etc etc )
they probably did not bother to obfuscate the code

Downoad Lutz Roeder`s Reflector for .Net ( Free )
http://www.aisto.com/roeder/dotnet/ and start decompiling and copy pasting
in a new project
i have done this in the past several times and although the code needs some
fixing it is not so hard to rewrite a program from a compiled dll or exe
this way

hth

Michel
 
M

Michael C

Michel Posseth said:
After rereading this thread to see if the issue is solved , as the subject
interests me , and thus getting more information about your problem
i have another option. :)


you told in the thread that fixing the component by the third party is
probably not an option, you also describe that the solution is made
inhouse by another department , this is getting interesting cause in that
case you might have the option to rewrite the component yourself ( no
issues with copyright etc etc )
they probably did not bother to obfuscate the code

Downoad Lutz Roeder`s Reflector for .Net ( Free )
http://www.aisto.com/roeder/dotnet/ and start decompiling and copy
pasting in a new project
i have done this in the past several times and although the code needs
some fixing it is not so hard to rewrite a program from a compiled dll or
exe this way

Good idea, I missed the fact that the dll is written in dotnet also. The
other option of course is to just ask for the source code :)

Michael
 

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

Similar Threads


Top