Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Memory leak .. 1

Status
Not open for further replies.

Nightsoft

Programmer
Aug 23, 2001
50
0
0
DK
Hi everybody.

Im making a system, which shows some incoming cases. The problem i have, is that I'm repeatedly running a sub, with 5 seconds interval.

What i do is connect to database (Access), get data if more posts than last, populate listbox and close objects.

My Listbox population is done, with a class module, which makes scroll bars to the listbox, if needed.

I've tried to make a step into to see, if i could see where the problem is, but I'm lost.

The function that I look through looks like this :
Code:
Sub ListSager()
  Dim MyConn As New ADODB.Connection
  Dim RSSag As New ADODB.Recordset
  Dim RSAntal As New ADODB.Recordset
  Dim ConnString As String
  
  ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\DB\CS-SupportDB.mdb;User Id=admin;Password=;"
 
  MyConn.ConnectionString = ConnString
  MyConn.Open
  
  SQLFindAntalSagerQuery = "SELECT COUNT(*) As SagsAntal FROM SagsTB WHERE Afviklet = false"
  Set RSAntal = MyConn.Execute(SQLFindAntalSagerQuery)
  
  If RSAntal("SagsAntal") > lblSagsAntal.Caption Then
    lstSagsList.Clear
    SQLFIndSagsInfoQuery = "SELECT Sag.SagsId, Sag.Dato, Sup.SupportType, MedArb.Navne, Sag.ProblemBeskrivelse FROM SagsTB Sag, SupportTypeTB Sup, MedarbejderTB MedArb WHERE Sag.SupportId = Sup.SupportId AND Sag.MedarbejderId = MedArb.MedarbejderId AND Sag.Afviklet = false"
    Set RSSag = MyConn.Execute(SQLFIndSagsInfoQuery)
  
    Do While Not (RSSag.BOF Or RSSag.EOF)
      LBHS.AddItemTab RSSag("SagsId") & _
           vbTab & RSSag("Dato") & _
           vbTab & RSSag("SupportType") & _
           vbTab & RSSag("Navne") & _
           vbTab & RSSag("ProblemBeskrivelse")
      RSSag.MoveNext
    Loop
    lblSagsAntal.Caption = RSAntal("SagsAntal")
  End If
  
  strInfo = "Info : " & RSAntal("SagsAntal") & " uafviklet sager"
  lblInfo.Caption = strInfo
  
  MyConn.Close
  Set MyConn = Nothing
  Set RSSag = Nothing
  Set RSAntal = Nothing
  
  Delay (5)
  If CallAgain = True Then
    ListSager
  End If
End Sub

The LBHS.AddItem is derived from this class function :

Code:
Public Sub AddItemTab(ByRef psItemText As String)
   Dim m As Long
   Dim hdc As Long
   Dim rc As RECT
   Dim hOldFont As Long
   Dim bHasVScrBar As Boolean
   
   mvarListBox.AddItem psItemText
   
   ' --- calculating the width of the currently added item ---
   hdc = GetDC(m_ListBoxHwnd) ' retrieving HDC for the listbox
   hOldFont = SelectObject(hdc, m_hItemFont) ' selecting the required font
   ' if you specify the DT_CALCRECT flag,
   ' DrawText only Determines the width and height of the rectangle
   ' required to display the text:
   DrawText hdc, psItemText, -1, rc, DT_SINGLELINE + DT_CALCRECT
   m = rc.Right - rc.Left + 150
   ' restoring the previous state
   Call SelectObject(hdc, hOldFont)
   ReleaseDC m_ListBoxHwnd, hdc
   
   ' --- determining whether we need to display the horizontal scroll bar ---
   If m > m_lMaxItemWidth Then
      m_lMaxItemWidth = m
      bHasVScrBar = GetWindowLong(m_ListBoxHwnd, GWL_STYLE) And WS_VSCROLL
      SendMessageByLong m_ListBoxHwnd, LB_SETHORIZONTALEXTENT, _
         m + IIf(bHasVScrBar, GetSystemMetrics(SM_CXVSCROLL), 4), 0
   End If
   
   ' --- scrolling the listbox to be sure that the user see the last item ---
   SendMessageByLong m_ListBoxHwnd, WM_VSCROLL, SB_BOTTOM, 0
End Sub

My delay, looks like this :

Code:
Public Sub Delay(lngSeconds As Long)
  Dim lngStart As Long
  Dim intstart As Integer
  lngStart = Timer

  Do While Timer <= lngStart + lngSeconds
    DoEvents
    If CallAgain = False Then
        Exit Do
    End If
  Loop
  Set Timer = Nothing
End Sub

When i make a step into, it'll repeat the ListSager() until it get's stack overflow, or VB just crashes, and shut's down.

For now, i'll keep on working, with the projekt, without the loop.. But I have to find a solution, or your solution :)

If anyone can see, what eats the memmory, I'll be so happy

Chers

Dennis

Machine code Rocks:)
 
ListSager appears to call itself if CallAgain is True, but CallAgain is not being set inside the loop (or anywhere that I can see). This will cause endless recursion (which is what you're seeing)

________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first

'If we're supposed to work in Hex, why have we only got A fingers?'
 
Hi there..

Sorry, for missing info :) The CallAgain is a globaly declared variable, which in Main, gets initialiced, as true.

In Unload i set it to false, so that when i close, the loop will be closed.
...
..?

Machine code Rocks:)
 
From a logic perspective - I have a big problem with a Sub calling itself because a) the stack gets full quickly (ie a so called memory leak) and b) the integrity of the local (Sub) variables can get compromised.

Instead of ListSager calling itself why not put the call to ListSager in a Do Until construct.

Comments?

&quot;Life is full of learning, and then there is wisdom&quot;
 
I have a problem with:

Set Timer = Nothing

For me, Timer returns a Single representing the number of seconds elapsed since midnight, and is not an object that you can set to Nothing. If that line is NOT causing an error, I think it should.

Have you got any error handling set to ignore errors? If you have then Delay won't work, and you may be masking another problem.

Try putting a couple of breakpoints in to check the value of CallAgain, and a MsgBox to check that Delay is working

________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first

'If we're supposed to work in Hex, why have we only got A fingers?'
 
johnwm,

Good observation -> a star to you.

&quot;Life is full of learning, and then there is wisdom&quot;
 
Hi there.

Sorry again.. It' was a leftover from me trying to close everything. . . But it isn't the timer. Though it made error, when setting delay on again.. But okay, when removed..

I tried to type call ListSager in my loop, it helped - but it keeps on going up. I'm not sure, what you mean with until construct.. I can figure out, that I have to make the call, but where do i start the loop..?

A little confused about what your meaning :)?

Thnx for your wuick reply's

Cheers

Dennis

Machine code Rocks:)
 
There's nothing wrong with a little recursion, so long as it's tightly controlled. Recursion can be a very powerful technique, but as people have suggested, watch the size of the call stack...

Something to realise here though is that a call stack being blown produces a very specific call stack error - it wouldn't present as a simple memory leak.

Having a leak built into the recursive function however, that would very quickly ruin your whole day... Objects are the culprits of choice here - if you create it, make damn sure you destroy it. DO NOT rely on garbage collection.

mmilan
 
mmilan -
Objects are the culprits of choice here - if you create it, make damn sure you destroy it. DO NOT rely on garbage collection.

This is the VB6 forum. ;-)

Stack overflows are uncontrolled recursion -- little doubt of that.

If you have a memory leak, use perfmon to watch your process's memory usage over time. The TaskManager isn't fine grained enough to do more than say memory is being consumed.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Hey koala. !

I finaly understood, that you meant a normal Do While. I got vonfused, with you saying construct, it made me thinking of some word from C and other languages... But amyway..

I've tried it, and it's stabalized, :)

Ive made a sub like this. :

Code:
Private Sub Form_Load()
  ...
  StartListing
End Sub

Private Sub Form_Unload(Cancel As Integer)
  CallAgain = False
  End
End Sub

Sub StartListing()
  CallAgain = true
  Do While CallAgain = true
    ListSager
    Delay(5)
  Loop
End Sub

And it just works :) Thnx people..

Cheers

Dennis


Machine code Rocks:)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top