Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / VB.NET / October 2007

Tip: Looking for answers? Try searching our database.

Memory creaping up...why?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jerry - 23 Oct 2007 16:27 GMT
I have a simple subroutine (see below) which reads a table and populates the
items of a combobox.  As the subroutine is executed, I'm watching the
taskmanager and the memory in use increases; however, once I get to the
Error_Exit: logic and start to close and dispose my memory variables, the
memory is not released and does not decrease in the task manager.  Why is
that?  Eventually, my program is giving me "Insufficient memory" errors.

****************************************************************************************

On Error GoTo Error_Handling

Dim cnn As New Odbc.OdbcConnection
Dim cmd As New Odbc.OdbcCommand
Dim rdr As Odbc.OdbcDataReader

cnn.ConnectionString = "dsn=" & accpac_companyid
cnn.Open()
cmd.Connection = cnn
cmd.CommandText = "select schedkey, scheddesc from cssktb order by schedkey"
rdr = cmd.ExecuteReader

Do While rdr.Read
   combo.Items.Add(rdr("schedkey").ToString.Trim)
Loop

Error_Exit:
   If Not IsNothing(rdr) Then
       rdr.Close()
       cmd.Connection.Close()
       cmd.Dispose()
       cnn.Close()
       cnn.Dispose()
   End If

   rdr = Nothing
   cmd = Nothing
   cnn = Nothing
Exit Sub

Error_Handling:
   Select Case Err.Number
   Case Else
       MsgBox("The following error occured in LoadSchedules()" & vbCrLf &
Err.Description)
   End Select

Resume Error_Exit
rowe_newsgroups - 23 Oct 2007 17:26 GMT
> I have a simple subroutine (see below) which reads a table and populates the
> items of a combobox.  As the subroutine is executed, I'm watching the
[quoted text clipped - 43 lines]
>
> Resume Error_Exit

Ugh - don't take this personal, but I hate your code, it brings back
unpleasant memories from my VB6 days. Anyways, I rewrote your using
Using blocks to dispose of the database objects, and replaced the
class VB style of error handling with .Net's try...catch blocks. I ran
a similar version (had to change it to connect to my SqlServer 2000
db) in an infinite loop and my memory never increased more than a few
100 kbs. Let me know if what your program does with the changes:

//////////////////////
       Try
           Using conn As New OdbcConnection(String.Format("dsn={0}",
accpac_companyid)), com As OdbcCommand = conn.CreateCommand
               conn.Open()
               com.CommandText = "selecte schedkey, scheddesc from
cssktb order by schedkey"

               Using dr As OdbcDataReader = com.ExecuteReader()
                   While dr.Read()

combo.Items.Add(dr("schedkey").ToString().Trim())
                   End While
               End Using
           End Using
       Catch ex As OdbcException
           MsgBox(String.Format("The following ODBC error occurred in
LoadSchedules() {0} {1}", Environment.NewLine, ex.Message))
       Catch ex As Exception
           MsgBox(String.Format("The following error occurred in
LoadSchedules() {0} {1}", Environment.NewLine, ex.Message))
       End Try
//////////////////////
rowe_newsgroups - 23 Oct 2007 17:27 GMT
> > I have a simple subroutine (see below) which reads a table and populates the
> > items of a combobox.  As the subroutine is executed, I'm watching the
[quoted text clipped - 75 lines]
>         End Try
> //////////////////////

Silly me I forgot to add:

////
Thanks,

Seth Rowe
////

To the end of my message (not that it really matters :-))

Thanks,

Seth Rowe
Jerry - 23 Oct 2007 18:04 GMT
Thanks Seth;
I used your example and it turns out to be a bit thinner on the memory usage
(12kb - if you believe Task Manager) so I will go with that and see if it
helps.  If anything, it's significantly less coding and I like the error
handling (ODBC vs general exceptions).

I've tried profiling the code with AntsProfiler (and many others), but I
have NO IDEA what I'm looking at there.  Am I wrong in assuming the memory
in use should return to the value before the subroutine executes if all the
variables are terminated properly?

Thanks again.

>> I have a simple subroutine (see below) which reads a table and populates
>> the
[quoted text clipped - 78 lines]
>        End Try
> //////////////////////
Jack Jackson - 23 Oct 2007 19:58 GMT
No, memory will not return to what it was when a method was invoked
when the method exits.  .NET has a garbage collector.  Memory will not
be freed until it is needed.

>Thanks Seth;
>I used your example and it turns out to be a bit thinner on the memory usage
[quoted text clipped - 91 lines]
>>        End Try
>> //////////////////////
Tom Shelton - 23 Oct 2007 20:40 GMT
> Thanks Seth;
> I used your example and it turns out to be a bit thinner on the memory usage
[quoted text clipped - 8 lines]
>
> Thanks again.

Several things to note...

The lifetime of a .net object is non-deteministic, due to the nature
of the garbage collector.  The only thing that can be said, is that
the reference will be freed at some point after there are no more
active references.  That being said, there is no point in setting
references to nothing at the end of your procedure, since they will be
out of scope and elligible for colleciton anyway.

The side affect of this is how to deal with unmanaged resources
(unmanaged meaning that they exist outside the scope of the runtime),
such as system handles, database connections, sockets, etc - since you
often want these sort of resources to behave in a deterministic way...

The answer to that is the use of the disposable pattern.   Objects,
that contain resources that should be released immediately, should
implement the IDisposable interface - which contains the single method
Dispose.  This is a signal to you that this object needs some
deterministic cleanup, and you should ensure that it is called when
you no longer need the object.  The easiest way to do this is to scope
the object in a Using block where possible, since this will ensure
that Dispose is called even if an error is raised.

As for your memory usage...  The taskmanager is not a good way to
profile memory.  There are lots of little tricks that windows plays to
make memory allocation quicker (like allocating a large initial
working set, not immediately releasing memory from a process when it
has been deallocated, etc) that are not immediately apparent by
looking at the taskmanager.  You should really be looking at the
performance monitor or a .net profiler...

--
Tom Shelton
Family Tree Mike - 23 Oct 2007 17:36 GMT
I wouldn't trust task manager memory reporting.  There are numerous reports
on this site regarding this.

Your code looks like vb6 migrated minimally as possible to compile in vb.net.
I think that you would benefit by recoding per MSDN examples.  The only thing
that jumps out at me would be that your error trap checks if rdr is nothing.
This
occurs after the connection is opened and command created.  You don't close
these if the failure happens before the reader creation.  I suspect this is
not
happening seems to work other than memory issues.

> I have a simple subroutine (see below) which reads a table and populates the
> items of a combobox.  As the subroutine is executed, I'm watching the
[quoted text clipped - 43 lines]
>
> Resume Error_Exit
Miro - 23 Oct 2007 18:21 GMT
The task manager shows an incorrect memory usage.

I once had a great link to an article
( similar to this one: http://www.itwriting.com/dotnetmem.php )

but it showed a step by step example with a hello world example.

Basically Windows automatically assigns "A Lot" of memory to an application, and
then if its needed it takes it away.
Something to do with "its easier to assign in the beginning, and take away later", than
adding more mid process.

M.

> I have a simple subroutine (see below) which reads a table and populates the
> items of a combobox.  As the subroutine is executed, I'm watching the
[quoted text clipped - 43 lines]
>
> Resume Error_Exit

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.