keeping memory resources cleaned up within timer loop of Windows Service

H

hazz

given
namespace WindowsService1
{
public class Service1 : System.ServiceProcess.ServiceBase.........

private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
ArrayList myAL = new ArrayList();
CustomClass objCont = new ControllerClass;
CustomClass objInfo = new InfoClass;

myAL = objCont.CreateArrayListofObjects()

for (int i = 0; i <= myAl.Count; i++){
objInfo = objCont.HydrateInfo_Object();
objCont.DoSomething(objInfo)
}
}
how do I think about this service from a memory allocation/deallocation
perspective? I would like to know just by looking at code that any
objects,arraylists,strings,integers that are created, are going to be
deallocated at the end of the timer process.

how do i think in the simplest way, about where and when I declare and
instantiate reference types so that I know they will be cleaned up.

If my main processing loop in my timer event which will loop n times every n
seconds is also instantiating other objects, each of which has its own
constructors and object declarations corresponding to typical application
needs, how do I think about the allocation/deallocation of those memory
resources? I want to make sure there are no memory orphans that I have
created when I simply set

Is there an article that would contain a fairly simple explanation of this?
After attempting to instrument my app into Perfmon, CLRProfiler and then
creating a trace class which logs memory info before and after each
function, I found this to be too complicated and reactive. If I knew exactly
what was going on just by looking at my initialization code, I wouldn't need
the instrumentation tools.

I know the same rules apply here as any application but given here that even
8 bytes that are not deallocated will be stolen from the available memory
people every time the timer fires. Within each firing of the timer is a loop
that could conceivably instantiate obects which themselves may not
deallocate their member variables. I don't want a memory leak, even a
trickle. ;-)

Thank you, -Greg
 
J

Jon Skeet [C# MVP]

hazz said:
given
namespace WindowsService1
{
public class Service1 : System.ServiceProcess.ServiceBase.........

private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
ArrayList myAL = new ArrayList();
CustomClass objCont = new ControllerClass;
CustomClass objInfo = new InfoClass;

myAL = objCont.CreateArrayListofObjects()

for (int i = 0; i <= myAl.Count; i++){
objInfo = objCont.HydrateInfo_Object();
objCont.DoSomething(objInfo)
}
}
how do I think about this service from a memory allocation/deallocation
perspective? I would like to know just by looking at code that any
objects,arraylists,strings,integers that are created, are going to be
deallocated at the end of the timer process.

They won't be. They'll be deallocated at some stage after that.
how do i think in the simplest way, about where and when I declare and
instantiate reference types so that I know they will be cleaned up.

If you're only using local variables and not storing the values
anywhere else which might cause them to hang around, they'll all be
*eligible* for garbage collection at the end of the method (and some of
them may be eligible earlier). That doesn't mean they'll be garbage
collected immediately, however.
If my main processing loop in my timer event which will loop n times every n
seconds is also instantiating other objects, each of which has its own
constructors and object declarations corresponding to typical application
needs, how do I think about the allocation/deallocation of those memory
resources? I want to make sure there are no memory orphans that I have
created when I simply set

Basically, think about what could get at the objects you've created. If
nothing can get to them any more, they're eligible for garbage
collection.
 
H

hazz

Basically, think about what could get at the objects you've created. If
nothing can get to them any more, they're eligible for garbage
collection.

Thank you for the reply Jon. I think what you said here was very key but I
am trying to understand better, with respect to looking at my code, is how
do I know if nothing can get to them anymore? Conversely, what I have to do
now is look for the objects for which something can get to them. And I am
still trying to get my arms around that. If I instantiate an object in a
loop, how does this fit into that test?

One specific question I had about my service is this. Presumably anything
that gets instantiated in a constructor is elgible for GC. Where is my
constructor in a service. I go right into my elapsed_time event with my main
loop which is creating objects, hydrating them, assigning values to string
and integer variables which are defined within that timer's elapsed event.

thanks again, -greg
 
J

Jon Skeet [C# MVP]

hazz said:
Thank you for the reply Jon. I think what you said here was very key but I
am trying to understand better, with respect to looking at my code, is how
do I know if nothing can get to them anymore?

Well, something can only get at an object if you've told it where it
is. Very few classes will store static references to objects you tell
them about, and hopefully they should make it very clear when they're
going to do so! So, work out which objects you've told about which
objects (eg which lists you've added references to) and make sure that
either those objects are eligible for garbage collection at the same
time, or that you've removed the references to the objects which you
*want* to be eligible.
Conversely, what I have to do
now is look for the objects for which something can get to them. And I am
still trying to get my arms around that. If I instantiate an object in a
loop, how does this fit into that test?

That depends on what you do with the object. If you add it to a list
for example, then it'll live at least as long as the list does, unless
you later remove it. If you just use the value of some property of the
object which doesn't know its "parent", then the object will be
eligible for garbage collection when the loop goes into its next
iteration.
One specific question I had about my service is this. Presumably anything
that gets instantiated in a constructor is elgible for GC. Where is my
constructor in a service. I go right into my elapsed_time event with my main
loop which is creating objects, hydrating them, assigning values to string
and integer variables which are defined within that timer's elapsed
event.

I can't remember much about how the services infrastructure works
(every so often I work it out but then forget it again), but I assume
that either you've got some code which *does* call a constructor, you
the parameterless constructor for your service is called automatically
by the services infrastructure.

It's not that "anything that gets instantiated in a constructor is
eligible for GC" - it's "anything which is no longer referenced"
wherever it's been instantiated.
 
H

hazz

Thank you so much for taking the time to explain it Jon. I know this is
basic stuff but it has been subtle. I am re-reading your explanation because
there are some key concepts I keep hearing, like objects whose references
have been removed.
Appreciatively,
-Greg
 
Top