471,319 Members | 1,441 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,319 software developers and data experts.

Windows Service Memory Usage

I know my problem has been discussed ad nauseum but I still don't get it so
please bear with me.

I have written a service which performs some work against a database once a
day (usually in the wee hours of the morning). From the time the service
starts to the first time it hits the database its memory consumption is
about 6.9MB which is a figure I can live with. However, after it hits the
database for the first time its memory jumps to 15MB and stays there. Now,
I'm a realist so 15MB isn't all that bad. I'm just looking to make the
service as slim as possible. so I would like, after it's finished with its
work if the memory could go back down to ~7MB. I'm wondering if there's a
better way to get rid of my database objects than what I'm doing now. Here's
the relevant portion of my service:

public class MyService: System.ServiceProcess.ServiceBase
{
private string timeToWork = "02:00";
private string startupVar2 = "something else";
private string configFileName = "MyService.cfg";
private System.Timers.Timer timer1 = null;
private EventLog appLog = null;
private SqlConnection sqlConnection = null;
private SqlDataAdapter da = null;
private DataTable dt = null;

public ETSReminder()
{
this.ServiceName = "MyService";
this.CanStop = true;
this.AutoLog = false;

appLog = new EventLog();
appLog.Source = "MyService";
}

// OnStart method starts the timer and adds the Elapsed event
// OnStop closes or disposes the service objects (

private void timer1_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.TimeOfDay >
Convert.ToDateTime(timeToWork).TimeOfDay &&
DateTime.Now.TimeOfDay <
Convert.ToDateTime(timeToWork).AddMinutes(5.5).Tim eOfDay)
{
DoWork();
}
}

private void DoWork()
{
try
{
ArrayList connectionStrings =
GetConnectionStrings(configFileName);
sqlConnection = new SqlConnection();

SqlCommand cmd1 = new SqlCommand("sproc1");
cmdCleanup.CommandType = CommandType.StoredProcedure;
cmdCleanup.Connection = sqlConnection;

SqlCommand cmd2 = new SqlCommand("sproc2");
cmdUserList.CommandType = CommandType.StoredProcedure;
cmdUserList.Connection = sqlConnection;

SqlCommand cmd3 = new SqlCommand("sproc3");
cmdReminderSent.CommandType = CommandType.StoredProcedure;
cmdReminderSent.Connection = sqlConnection;

foreach (string connectionString in connectionStrings)
{
sqlConnection.ConnectionString = connectionString;
sqlConnection.Open();

cmd1.ExecuteNonQuery();

da = new SqlDataAdapter(cmd2);
dt = new DataTable();
da.Fill(dt);

foreach (DataRow dr in dt.Rows)
{
// Does stuff including sending some email
cmd3.ExecuteNonQuery();
}

sqlConnection.Close();
}
}
catch
{
// Handle any exceptions
}
finally
{
dt.Dispose();
da.Dispose();
sqlConnection.Dispose();
}
}

}

---end code---

I have the database objects as class variables in case something hangs while
it's working, I can close the connection from my error handling routines.

I have even tried adding GC.Collect() after I dispose sqlConnection but that
doesn't seem to make the memory ever go down.

I have another more sinister problem in that each time the timer1_Elapsed
runs about 20K of memory is added that never goes away. Since this is a 24/7
service this could be an even bigger problem.

I have no ego over my code so if I'm doing something dumb please tell me.
Otherwise I would love to hear any ideas how I may solve my two memory
issues.

Thanks,
nautonnier
Jan 22 '06 #1
8 7475
you know where it says "public ETSReminder()"? you should probably change
that in your head to "public MyService()" and forget you ever saw what it
was really called.<g>
Jan 22 '06 #2
Nautonnier,
if your service only needs to perform its action once per day, I believe you
would be far better off with a console Executable that gets kicked off at the
proper time via an entry in Task Scheduler.

In this manner, once it's done, it will exit cleanly and there will be no
memory consumption for the next 24 hours.
Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"nautonnier" wrote:
I know my problem has been discussed ad nauseum but I still don't get it so
please bear with me.

I have written a service which performs some work against a database once a
day (usually in the wee hours of the morning). From the time the service
starts to the first time it hits the database its memory consumption is
about 6.9MB which is a figure I can live with. However, after it hits the
database for the first time its memory jumps to 15MB and stays there. Now,
I'm a realist so 15MB isn't all that bad. I'm just looking to make the
service as slim as possible. so I would like, after it's finished with its
work if the memory could go back down to ~7MB. I'm wondering if there's a
better way to get rid of my database objects than what I'm doing now. Here's
the relevant portion of my service:

public class MyService: System.ServiceProcess.ServiceBase
{
private string timeToWork = "02:00";
private string startupVar2 = "something else";
private string configFileName = "MyService.cfg";
private System.Timers.Timer timer1 = null;
private EventLog appLog = null;
private SqlConnection sqlConnection = null;
private SqlDataAdapter da = null;
private DataTable dt = null;

public ETSReminder()
{
this.ServiceName = "MyService";
this.CanStop = true;
this.AutoLog = false;

appLog = new EventLog();
appLog.Source = "MyService";
}

// OnStart method starts the timer and adds the Elapsed event
// OnStop closes or disposes the service objects (

private void timer1_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.TimeOfDay >
Convert.ToDateTime(timeToWork).TimeOfDay &&
DateTime.Now.TimeOfDay <
Convert.ToDateTime(timeToWork).AddMinutes(5.5).Tim eOfDay)
{
DoWork();
}
}

private void DoWork()
{
try
{
ArrayList connectionStrings =
GetConnectionStrings(configFileName);
sqlConnection = new SqlConnection();

SqlCommand cmd1 = new SqlCommand("sproc1");
cmdCleanup.CommandType = CommandType.StoredProcedure;
cmdCleanup.Connection = sqlConnection;

SqlCommand cmd2 = new SqlCommand("sproc2");
cmdUserList.CommandType = CommandType.StoredProcedure;
cmdUserList.Connection = sqlConnection;

SqlCommand cmd3 = new SqlCommand("sproc3");
cmdReminderSent.CommandType = CommandType.StoredProcedure;
cmdReminderSent.Connection = sqlConnection;

foreach (string connectionString in connectionStrings)
{
sqlConnection.ConnectionString = connectionString;
sqlConnection.Open();

cmd1.ExecuteNonQuery();

da = new SqlDataAdapter(cmd2);
dt = new DataTable();
da.Fill(dt);

foreach (DataRow dr in dt.Rows)
{
// Does stuff including sending some email
cmd3.ExecuteNonQuery();
}

sqlConnection.Close();
}
}
catch
{
// Handle any exceptions
}
finally
{
dt.Dispose();
da.Dispose();
sqlConnection.Dispose();
}
}

}

---end code---

I have the database objects as class variables in case something hangs while
it's working, I can close the connection from my error handling routines.

I have even tried adding GC.Collect() after I dispose sqlConnection but that
doesn't seem to make the memory ever go down.

I have another more sinister problem in that each time the timer1_Elapsed
runs about 20K of memory is added that never goes away. Since this is a 24/7
service this could be an even bigger problem.

I have no ego over my code so if I'm doing something dumb please tell me.
Otherwise I would love to hear any ideas how I may solve my two memory
issues.

Thanks,
nautonnier

Jan 22 '06 #3
Have you tried running a memory profiler.

there are many commercial profilers like Devpartner (compuware) or ANTS
(redgate) ...

Or you can use a free one from Microsoft (CLR profiler) .. It may give
you a clue of what is happening in your code.
http://msdn.microsoft.com/library/de...nethowto13.asp
--
Regards,
David Hernández Díez
MCDBA MCSD vs6 & .NET
DCE5 .Net1.1 & DCE2 .NET 2.0

nautonnier wrote:
I know my problem has been discussed ad nauseum but I still don't get it so
please bear with me.

I have written a service which performs some work against a database once a
day (usually in the wee hours of the morning). From the time the service
starts to the first time it hits the database its memory consumption is
about 6.9MB which is a figure I can live with. However, after it hits the
database for the first time its memory jumps to 15MB and stays there. Now,
I'm a realist so 15MB isn't all that bad. I'm just looking to make the
service as slim as possible. so I would like, after it's finished with its
work if the memory could go back down to ~7MB. I'm wondering if there's a
better way to get rid of my database objects than what I'm doing now. Here's
the relevant portion of my service:

public class MyService: System.ServiceProcess.ServiceBase
{
private string timeToWork = "02:00";
private string startupVar2 = "something else";
private string configFileName = "MyService.cfg";
private System.Timers.Timer timer1 = null;
private EventLog appLog = null;
private SqlConnection sqlConnection = null;
private SqlDataAdapter da = null;
private DataTable dt = null;

public ETSReminder()
{
this.ServiceName = "MyService";
this.CanStop = true;
this.AutoLog = false;

appLog = new EventLog();
appLog.Source = "MyService";
}

// OnStart method starts the timer and adds the Elapsed event
// OnStop closes or disposes the service objects (

private void timer1_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.TimeOfDay >
Convert.ToDateTime(timeToWork).TimeOfDay &&
DateTime.Now.TimeOfDay <
Convert.ToDateTime(timeToWork).AddMinutes(5.5).Tim eOfDay)
{
DoWork();
}
}

private void DoWork()
{
try
{
ArrayList connectionStrings =
GetConnectionStrings(configFileName);
sqlConnection = new SqlConnection();

SqlCommand cmd1 = new SqlCommand("sproc1");
cmdCleanup.CommandType = CommandType.StoredProcedure;
cmdCleanup.Connection = sqlConnection;

SqlCommand cmd2 = new SqlCommand("sproc2");
cmdUserList.CommandType = CommandType.StoredProcedure;
cmdUserList.Connection = sqlConnection;

SqlCommand cmd3 = new SqlCommand("sproc3");
cmdReminderSent.CommandType = CommandType.StoredProcedure;
cmdReminderSent.Connection = sqlConnection;

foreach (string connectionString in connectionStrings)
{
sqlConnection.ConnectionString = connectionString;
sqlConnection.Open();

cmd1.ExecuteNonQuery();

da = new SqlDataAdapter(cmd2);
dt = new DataTable();
da.Fill(dt);

foreach (DataRow dr in dt.Rows)
{
// Does stuff including sending some email
cmd3.ExecuteNonQuery();
}

sqlConnection.Close();
}
}
catch
{
// Handle any exceptions
}
finally
{
dt.Dispose();
da.Dispose();
sqlConnection.Dispose();
}
}

}

---end code---

I have the database objects as class variables in case something hangs while
it's working, I can close the connection from my error handling routines.

I have even tried adding GC.Collect() after I dispose sqlConnection but that
doesn't seem to make the memory ever go down.

I have another more sinister problem in that each time the timer1_Elapsed
runs about 20K of memory is added that never goes away. Since this is a 24/7
service this could be an even bigger problem.

I have no ego over my code so if I'm doing something dumb please tell me.
Otherwise I would love to hear any ideas how I may solve my two memory
issues.

Thanks,
nautonnier


Jan 22 '06 #4
That's not a bad idea Peter, except that I have no control over what happens
in the client environment and Task Scheduler may not even be enabled. Thus,
it was decided to go with a service.

-nautonnier
"Peter Bromberg [C# MVP]" <pb*******@yahoo.nospammin.com> wrote in message
news:51**********************************@microsof t.com...
Nautonnier,
if your service only needs to perform its action once per day, I believe you would be far better off with a console Executable that gets kicked off at the proper time via an entry in Task Scheduler.

In this manner, once it's done, it will exit cleanly and there will be no
memory consumption for the next 24 hours.
Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"nautonnier" wrote:
I know my problem has been discussed ad nauseum but I still don't get it so please bear with me.

I have written a service which performs some work against a database once a day (usually in the wee hours of the morning). From the time the service
starts to the first time it hits the database its memory consumption is
about 6.9MB which is a figure I can live with. However, after it hits the database for the first time its memory jumps to 15MB and stays there. Now, I'm a realist so 15MB isn't all that bad. I'm just looking to make the
service as slim as possible. so I would like, after it's finished with its work if the memory could go back down to ~7MB. I'm wondering if there's a better way to get rid of my database objects than what I'm doing now. Here's the relevant portion of my service:

public class MyService: System.ServiceProcess.ServiceBase
{
private string timeToWork = "02:00";
private string startupVar2 = "something else";
private string configFileName = "MyService.cfg";
private System.Timers.Timer timer1 = null;
private EventLog appLog = null;
private SqlConnection sqlConnection = null;
private SqlDataAdapter da = null;
private DataTable dt = null;

public ETSReminder()
{
this.ServiceName = "MyService";
this.CanStop = true;
this.AutoLog = false;

appLog = new EventLog();
appLog.Source = "MyService";
}

// OnStart method starts the timer and adds the Elapsed event
// OnStop closes or disposes the service objects (

private void timer1_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.TimeOfDay >
Convert.ToDateTime(timeToWork).TimeOfDay &&
DateTime.Now.TimeOfDay <
Convert.ToDateTime(timeToWork).AddMinutes(5.5).Tim eOfDay)
{
DoWork();
}
}

private void DoWork()
{
try
{
ArrayList connectionStrings =
GetConnectionStrings(configFileName);
sqlConnection = new SqlConnection();

SqlCommand cmd1 = new SqlCommand("sproc1");
cmdCleanup.CommandType = CommandType.StoredProcedure;
cmdCleanup.Connection = sqlConnection;

SqlCommand cmd2 = new SqlCommand("sproc2");
cmdUserList.CommandType = CommandType.StoredProcedure;
cmdUserList.Connection = sqlConnection;

SqlCommand cmd3 = new SqlCommand("sproc3");
cmdReminderSent.CommandType = CommandType.StoredProcedure;
cmdReminderSent.Connection = sqlConnection;

foreach (string connectionString in connectionStrings)
{
sqlConnection.ConnectionString = connectionString;
sqlConnection.Open();

cmd1.ExecuteNonQuery();

da = new SqlDataAdapter(cmd2);
dt = new DataTable();
da.Fill(dt);

foreach (DataRow dr in dt.Rows)
{
// Does stuff including sending some email
cmd3.ExecuteNonQuery();
}

sqlConnection.Close();
}
}
catch
{
// Handle any exceptions
}
finally
{
dt.Dispose();
da.Dispose();
sqlConnection.Dispose();
}
}

}

---end code---

I have the database objects as class variables in case something hangs while it's working, I can close the connection from my error handling routines.
I have even tried adding GC.Collect() after I dispose sqlConnection but that doesn't seem to make the memory ever go down.

I have another more sinister problem in that each time the timer1_Elapsed runs about 20K of memory is added that never goes away. Since this is a 24/7 service this could be an even bigger problem.

I have no ego over my code so if I'm doing something dumb please tell me. Otherwise I would love to hear any ideas how I may solve my two memory
issues.

Thanks,
nautonnier

Jan 23 '06 #5
Task scheduler itself is a service, if a user is allowed to disable the
scheduler, who will stop him to disable your service?
It's a bad idea to continuously waste precious resources for a service that
effectively does some work only once per 24 hours for about a few seconds.

Willy.
"nautonnier" <onTheLambFromAllThatSpam> wrote in message
news:Oh**************@tk2msftngp13.phx.gbl...
| That's not a bad idea Peter, except that I have no control over what
happens
| in the client environment and Task Scheduler may not even be enabled.
Thus,
| it was decided to go with a service.
|
| -nautonnier
|
|
| "Peter Bromberg [C# MVP]" <pb*******@yahoo.nospammin.com> wrote in message
| news:51**********************************@microsof t.com...
| > Nautonnier,
| > if your service only needs to perform its action once per day, I believe
| you
| > would be far better off with a console Executable that gets kicked off
at
| the
| > proper time via an entry in Task Scheduler.
| >
| > In this manner, once it's done, it will exit cleanly and there will be
no
| > memory consumption for the next 24 hours.
| > Peter
| >
| > --
| > Co-founder, Eggheadcafe.com developer portal:
| > http://www.eggheadcafe.com
| > UnBlog:
| > http://petesbloggerama.blogspot.com
| >
| >
| >
| >
| > "nautonnier" wrote:
| >
| > > I know my problem has been discussed ad nauseum but I still don't get
it
| so
| > > please bear with me.
| > >
| > > I have written a service which performs some work against a database
| once a
| > > day (usually in the wee hours of the morning). From the time the
service
| > > starts to the first time it hits the database its memory consumption
is
| > > about 6.9MB which is a figure I can live with. However, after it hits
| the
| > > database for the first time its memory jumps to 15MB and stays there.
| Now,
| > > I'm a realist so 15MB isn't all that bad. I'm just looking to make the
| > > service as slim as possible. so I would like, after it's finished with
| its
| > > work if the memory could go back down to ~7MB. I'm wondering if
there's
| a
| > > better way to get rid of my database objects than what I'm doing now.
| Here's
| > > the relevant portion of my service:
| > >
| > > public class MyService: System.ServiceProcess.ServiceBase
| > > {
| > > private string timeToWork = "02:00";
| > > private string startupVar2 = "something else";
| > > private string configFileName = "MyService.cfg";
| > > private System.Timers.Timer timer1 = null;
| > > private EventLog appLog = null;
| > > private SqlConnection sqlConnection = null;
| > > private SqlDataAdapter da = null;
| > > private DataTable dt = null;
| > >
| > > public ETSReminder()
| > > {
| > > this.ServiceName = "MyService";
| > > this.CanStop = true;
| > > this.AutoLog = false;
| > >
| > > appLog = new EventLog();
| > > appLog.Source = "MyService";
| > > }
| > >
| > > // OnStart method starts the timer and adds the Elapsed event
| > > // OnStop closes or disposes the service objects (
| > >
| > > private void timer1_Elapsed(object sender,
| > > System.Timers.ElapsedEventArgs e)
| > > {
| > > if (DateTime.Now.TimeOfDay >
| > > Convert.ToDateTime(timeToWork).TimeOfDay &&
| > > DateTime.Now.TimeOfDay <
| > > Convert.ToDateTime(timeToWork).AddMinutes(5.5).Tim eOfDay)
| > > {
| > > DoWork();
| > > }
| > > }
| > >
| > > private void DoWork()
| > > {
| > > try
| > > {
| > > ArrayList connectionStrings =
| > > GetConnectionStrings(configFileName);
| > > sqlConnection = new SqlConnection();
| > >
| > > SqlCommand cmd1 = new SqlCommand("sproc1");
| > > cmdCleanup.CommandType = CommandType.StoredProcedure;
| > > cmdCleanup.Connection = sqlConnection;
| > >
| > > SqlCommand cmd2 = new SqlCommand("sproc2");
| > > cmdUserList.CommandType = CommandType.StoredProcedure;
| > > cmdUserList.Connection = sqlConnection;
| > >
| > > SqlCommand cmd3 = new SqlCommand("sproc3");
| > > cmdReminderSent.CommandType = CommandType.StoredProcedure;
| > > cmdReminderSent.Connection = sqlConnection;
| > >
| > > foreach (string connectionString in connectionStrings)
| > > {
| > > sqlConnection.ConnectionString = connectionString;
| > > sqlConnection.Open();
| > >
| > > cmd1.ExecuteNonQuery();
| > >
| > > da = new SqlDataAdapter(cmd2);
| > > dt = new DataTable();
| > > da.Fill(dt);
| > >
| > > foreach (DataRow dr in dt.Rows)
| > > {
| > > // Does stuff including sending some email
| > > cmd3.ExecuteNonQuery();
| > > }
| > >
| > > sqlConnection.Close();
| > > }
| > > }
| > > catch
| > > {
| > > // Handle any exceptions
| > > }
| > > finally
| > > {
| > > dt.Dispose();
| > > da.Dispose();
| > > sqlConnection.Dispose();
| > > }
| > > }
| > >
| > > }
| > >
| > > ---end code---
| > >
| > > I have the database objects as class variables in case something hangs
| while
| > > it's working, I can close the connection from my error handling
| routines.
| > >
| > > I have even tried adding GC.Collect() after I dispose sqlConnection
but
| that
| > > doesn't seem to make the memory ever go down.
| > >
| > > I have another more sinister problem in that each time the
| timer1_Elapsed
| > > runs about 20K of memory is added that never goes away. Since this is
a
| 24/7
| > > service this could be an even bigger problem.
| > >
| > > I have no ego over my code so if I'm doing something dumb please tell
| me.
| > > Otherwise I would love to hear any ideas how I may solve my two memory
| > > issues.
| > >
| > > Thanks,
| > > nautonnier
| > >
| > >
| > >
|
|
Jan 23 '06 #6
My point was all this was discussed with the client and this was the way
they wanted to go.

"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:%2***************@TK2MSFTNGP12.phx.gbl...
Task scheduler itself is a service, if a user is allowed to disable the
scheduler, who will stop him to disable your service?
It's a bad idea to continuously waste precious resources for a service that effectively does some work only once per 24 hours for about a few seconds.

Willy.
"nautonnier" <onTheLambFromAllThatSpam> wrote in message
news:Oh**************@tk2msftngp13.phx.gbl...
| That's not a bad idea Peter, except that I have no control over what
happens
| in the client environment and Task Scheduler may not even be enabled.
Thus,
| it was decided to go with a service.
|
| -nautonnier
|
|
| "Peter Bromberg [C# MVP]" <pb*******@yahoo.nospammin.com> wrote in message | news:51**********************************@microsof t.com...
| > Nautonnier,
| > if your service only needs to perform its action once per day, I believe | you
| > would be far better off with a console Executable that gets kicked off
at
| the
| > proper time via an entry in Task Scheduler.
| >
| > In this manner, once it's done, it will exit cleanly and there will be
no
| > memory consumption for the next 24 hours.
| > Peter
| >
| > --
| > Co-founder, Eggheadcafe.com developer portal:
| > http://www.eggheadcafe.com
| > UnBlog:
| > http://petesbloggerama.blogspot.com
| >
| >
| >
| >
| > "nautonnier" wrote:
| >
| > > I know my problem has been discussed ad nauseum but I still don't get it
| so
| > > please bear with me.
| > >
| > > I have written a service which performs some work against a database
| once a
| > > day (usually in the wee hours of the morning). From the time the
service
| > > starts to the first time it hits the database its memory consumption
is
| > > about 6.9MB which is a figure I can live with. However, after it hits | the
| > > database for the first time its memory jumps to 15MB and stays there. | Now,
| > > I'm a realist so 15MB isn't all that bad. I'm just looking to make the | > > service as slim as possible. so I would like, after it's finished with | its
| > > work if the memory could go back down to ~7MB. I'm wondering if
there's
| a
| > > better way to get rid of my database objects than what I'm doing now. | Here's
| > > the relevant portion of my service:
| > >
| > > public class MyService: System.ServiceProcess.ServiceBase
| > > {
| > > private string timeToWork = "02:00";
| > > private string startupVar2 = "something else";
| > > private string configFileName = "MyService.cfg";
| > > private System.Timers.Timer timer1 = null;
| > > private EventLog appLog = null;
| > > private SqlConnection sqlConnection = null;
| > > private SqlDataAdapter da = null;
| > > private DataTable dt = null;
| > >
| > > public ETSReminder()
| > > {
| > > this.ServiceName = "MyService";
| > > this.CanStop = true;
| > > this.AutoLog = false;
| > >
| > > appLog = new EventLog();
| > > appLog.Source = "MyService";
| > > }
| > >
| > > // OnStart method starts the timer and adds the Elapsed event
| > > // OnStop closes or disposes the service objects (
| > >
| > > private void timer1_Elapsed(object sender,
| > > System.Timers.ElapsedEventArgs e)
| > > {
| > > if (DateTime.Now.TimeOfDay >
| > > Convert.ToDateTime(timeToWork).TimeOfDay &&
| > > DateTime.Now.TimeOfDay <
| > > Convert.ToDateTime(timeToWork).AddMinutes(5.5).Tim eOfDay)
| > > {
| > > DoWork();
| > > }
| > > }
| > >
| > > private void DoWork()
| > > {
| > > try
| > > {
| > > ArrayList connectionStrings =
| > > GetConnectionStrings(configFileName);
| > > sqlConnection = new SqlConnection();
| > >
| > > SqlCommand cmd1 = new SqlCommand("sproc1");
| > > cmdCleanup.CommandType = CommandType.StoredProcedure;
| > > cmdCleanup.Connection = sqlConnection;
| > >
| > > SqlCommand cmd2 = new SqlCommand("sproc2");
| > > cmdUserList.CommandType = CommandType.StoredProcedure;
| > > cmdUserList.Connection = sqlConnection;
| > >
| > > SqlCommand cmd3 = new SqlCommand("sproc3");
| > > cmdReminderSent.CommandType = CommandType.StoredProcedure; | > > cmdReminderSent.Connection = sqlConnection;
| > >
| > > foreach (string connectionString in connectionStrings)
| > > {
| > > sqlConnection.ConnectionString = connectionString;
| > > sqlConnection.Open();
| > >
| > > cmd1.ExecuteNonQuery();
| > >
| > > da = new SqlDataAdapter(cmd2);
| > > dt = new DataTable();
| > > da.Fill(dt);
| > >
| > > foreach (DataRow dr in dt.Rows)
| > > {
| > > // Does stuff including sending some email
| > > cmd3.ExecuteNonQuery();
| > > }
| > >
| > > sqlConnection.Close();
| > > }
| > > }
| > > catch
| > > {
| > > // Handle any exceptions
| > > }
| > > finally
| > > {
| > > dt.Dispose();
| > > da.Dispose();
| > > sqlConnection.Dispose();
| > > }
| > > }
| > >
| > > }
| > >
| > > ---end code---
| > >
| > > I have the database objects as class variables in case something hangs | while
| > > it's working, I can close the connection from my error handling
| routines.
| > >
| > > I have even tried adding GC.Collect() after I dispose sqlConnection
but
| that
| > > doesn't seem to make the memory ever go down.
| > >
| > > I have another more sinister problem in that each time the
| timer1_Elapsed
| > > runs about 20K of memory is added that never goes away. Since this is a
| 24/7
| > > service this could be an even bigger problem.
| > >
| > > I have no ego over my code so if I'm doing something dumb please tell | me.
| > > Otherwise I would love to hear any ideas how I may solve my two memory | > > issues.
| > >
| > > Thanks,
| > > nautonnier
| > >
| > >
| > >
|
|

Jan 23 '06 #7
So I guess my first pointed question is wouldn't the call to dispose of the
connection, dataadapter and datatable objects mark them so the GC reclaims
their memory and shouldn't that conceivably occur within 5 minutes? Would
this not also be true of the command objects once they went out of scope at
the end of DoWork()?

At this point I'm trying to understand things at a deeper level and
hopefully become a better programmer.

"nautonnier" <onTheLambFromAllThatSpam> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
I know my problem has been discussed ad nauseum but I still don't get it so please bear with me.

I have written a service which performs some work against a database once a day (usually in the wee hours of the morning). From the time the service
starts to the first time it hits the database its memory consumption is
about 6.9MB which is a figure I can live with. However, after it hits the
database for the first time its memory jumps to 15MB and stays there. Now,
I'm a realist so 15MB isn't all that bad. I'm just looking to make the
service as slim as possible. so I would like, after it's finished with its
work if the memory could go back down to ~7MB. I'm wondering if there's a
better way to get rid of my database objects than what I'm doing now. Here's the relevant portion of my service:

public class MyService: System.ServiceProcess.ServiceBase
{
private string timeToWork = "02:00";
private string startupVar2 = "something else";
private string configFileName = "MyService.cfg";
private System.Timers.Timer timer1 = null;
private EventLog appLog = null;
private SqlConnection sqlConnection = null;
private SqlDataAdapter da = null;
private DataTable dt = null;

public ETSReminder()
{
this.ServiceName = "MyService";
this.CanStop = true;
this.AutoLog = false;

appLog = new EventLog();
appLog.Source = "MyService";
}

// OnStart method starts the timer and adds the Elapsed event
// OnStop closes or disposes the service objects (

private void timer1_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.TimeOfDay >
Convert.ToDateTime(timeToWork).TimeOfDay &&
DateTime.Now.TimeOfDay <
Convert.ToDateTime(timeToWork).AddMinutes(5.5).Tim eOfDay)
{
DoWork();
}
}

private void DoWork()
{
try
{
ArrayList connectionStrings =
GetConnectionStrings(configFileName);
sqlConnection = new SqlConnection();

SqlCommand cmd1 = new SqlCommand("sproc1");
cmdCleanup.CommandType = CommandType.StoredProcedure;
cmdCleanup.Connection = sqlConnection;

SqlCommand cmd2 = new SqlCommand("sproc2");
cmdUserList.CommandType = CommandType.StoredProcedure;
cmdUserList.Connection = sqlConnection;

SqlCommand cmd3 = new SqlCommand("sproc3");
cmdReminderSent.CommandType = CommandType.StoredProcedure;
cmdReminderSent.Connection = sqlConnection;

foreach (string connectionString in connectionStrings)
{
sqlConnection.ConnectionString = connectionString;
sqlConnection.Open();

cmd1.ExecuteNonQuery();

da = new SqlDataAdapter(cmd2);
dt = new DataTable();
da.Fill(dt);

foreach (DataRow dr in dt.Rows)
{
// Does stuff including sending some email
cmd3.ExecuteNonQuery();
}

sqlConnection.Close();
}
}
catch
{
// Handle any exceptions
}
finally
{
dt.Dispose();
da.Dispose();
sqlConnection.Dispose();
}
}

}

---end code---

I have the database objects as class variables in case something hangs while it's working, I can close the connection from my error handling routines.

I have even tried adding GC.Collect() after I dispose sqlConnection but that doesn't seem to make the memory ever go down.

I have another more sinister problem in that each time the timer1_Elapsed
runs about 20K of memory is added that never goes away. Since this is a 24/7 service this could be an even bigger problem.

I have no ego over my code so if I'm doing something dumb please tell me.
Otherwise I would love to hear any ideas how I may solve my two memory
issues.

Thanks,
nautonnier

Jan 23 '06 #8
Laika
1
So I guess my first pointed question is wouldn't the call to dispose of the
connection, dataadapter and datatable objects mark them so the GC reclaims
their memory and shouldn't that conceivably occur within 5 minutes? Would
this not also be true of the command objects once they went out of scope at
the end of DoWork()?

At this point I'm trying to understand things at a deeper level and
hopefully become a better programmer.
My guess is that your program isn't using up the memory it's been allocated and the GC won't be called for your app until you've used up your memory and a New() is requested.
May 1 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Frank Esser | last post: by
2 posts views Thread by Mikael Sorensen | last post: by
7 posts views Thread by George Gre | last post: by
8 posts views Thread by Greg Merideth | last post: by
7 posts views Thread by HeatherS | last post: by
1 post views Thread by Frank Rizzo | last post: by
2 posts views Thread by jld | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.