Memory Leak in Sub ?
-
Hi, I've narrowed down a memory leak in my application to a single Sub, however, I can't figure out what's doing it. Whenever this Sub is called (SelectedIndexChanged), my memory usage grows by ~100 kb and doesn't go down, according to Task Manager. Here's my code: Note: The following names are Global Variables: appSelPath appSelName appSelAlt appSelPos appSelID canEnable beenFound And yes, I need all of these variables as they are used in many other methods within my application.
Dim selectedText As String = "" If lbApps.SelectedItems.Count = 1 Then btnLaunch.Enabled = True pbSel.Image = ilApps.Images(lbApps.SelectedIndex + 1) 'lvApps.SelectedItems(0).ImageList.Images(selImg) selectedText = lbApps.SelectedItem.ToString btnLaunch.Text = "Launch " + selectedText btnMove.Text = strMoveText.Replace("|", selectedText) 'Add Application Routine If selectedText <> "Add Application..." Then 'set app selected path For i As Integer = 0 To appListing.Count - 1 Dim lineData() As String = appListing.Item(i).ToString.Split("|") If selectedText = lineData(0) Then appSelPath = lineData(1) appSelName = lineData(0) If lineData.Length = 3 Then If lineData(2) = "True" Then appSelAlt = True Else appSelAlt = False End If End If Array.Clear(lineData, 0, lineData.Length) lineData = Nothing Next Dim enableIt As Boolean = True ' Dim appPos As Integer = -10 For i As Integer = 0 To appLaunched.Count - 1 Dim lineData() As String = appLaunched.Item(i).ToString.Split("|") If lineData(1) <> "wait" Then If appSelName = lineData(0) Then enableIt = False If CInt(lineData(1)) > 0 Then appSelPos = CInt(lineData(1)) appSelID = CInt(lineData(2)) canEnable = True End If End If End If Array.Clear(lineD
-
Hi, I've narrowed down a memory leak in my application to a single Sub, however, I can't figure out what's doing it. Whenever this Sub is called (SelectedIndexChanged), my memory usage grows by ~100 kb and doesn't go down, according to Task Manager. Here's my code: Note: The following names are Global Variables: appSelPath appSelName appSelAlt appSelPos appSelID canEnable beenFound And yes, I need all of these variables as they are used in many other methods within my application.
Dim selectedText As String = "" If lbApps.SelectedItems.Count = 1 Then btnLaunch.Enabled = True pbSel.Image = ilApps.Images(lbApps.SelectedIndex + 1) 'lvApps.SelectedItems(0).ImageList.Images(selImg) selectedText = lbApps.SelectedItem.ToString btnLaunch.Text = "Launch " + selectedText btnMove.Text = strMoveText.Replace("|", selectedText) 'Add Application Routine If selectedText <> "Add Application..." Then 'set app selected path For i As Integer = 0 To appListing.Count - 1 Dim lineData() As String = appListing.Item(i).ToString.Split("|") If selectedText = lineData(0) Then appSelPath = lineData(1) appSelName = lineData(0) If lineData.Length = 3 Then If lineData(2) = "True" Then appSelAlt = True Else appSelAlt = False End If End If Array.Clear(lineData, 0, lineData.Length) lineData = Nothing Next Dim enableIt As Boolean = True ' Dim appPos As Integer = -10 For i As Integer = 0 To appLaunched.Count - 1 Dim lineData() As String = appLaunched.Item(i).ToString.Split("|") If lineData(1) <> "wait" Then If appSelName = lineData(0) Then enableIt = False If CInt(lineData(1)) > 0 Then appSelPos = CInt(lineData(1)) appSelID = CInt(lineData(2)) canEnable = True End If End If End If Array.Clear(lineD
Mitch F. wrote:
Note: The following names are Global Variables: appSelPath appSelName appSelAlt appSelPos appSelID canEnable beenFound
Nasty.... What makes you think this is leaking memory ?
Christian Graus Please read this if you don't understand the answer I've given you "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
-
Mitch F. wrote:
Note: The following names are Global Variables: appSelPath appSelName appSelAlt appSelPos appSelID canEnable beenFound
Nasty.... What makes you think this is leaking memory ?
Christian Graus Please read this if you don't understand the answer I've given you "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
-
Hmm... so even if global variables are handled correctly, they will still cause an extremely large growth in memory consumption? Is there any more efficient way to carry variables from one sub to another?
I see no reason for this to leak memory. I assume you really mean it uses more memory than you would like. No object in this method can leak memory. Globals won't leak, they are just a poor design. Yes, you can pass variables as parameters, or use delegates if classes need to communicate when a value changes.
Christian Graus Please read this if you don't understand the answer I've given you "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
-
I see no reason for this to leak memory. I assume you really mean it uses more memory than you would like. No object in this method can leak memory. Globals won't leak, they are just a poor design. Yes, you can pass variables as parameters, or use delegates if classes need to communicate when a value changes.
Christian Graus Please read this if you don't understand the answer I've given you "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
Hi, Thanks for the responses. I've created a quick application (using one textbox and one button) to see if global variables are eating up memory and not releasing it, and that seems to be the case.
Public Class Form1 Dim globalString As String = "" Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged globalString = TextBox1.Text End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click TextBox1.Text = "" globalString = Nothing End Sub End Class
When I add text to the global variable, the memory starts to get eaten pretty quickly, but when I click the button to set the variable to Nothing, the memory still isn't released, but more memory is taken. Thanks, Mitch F -
Hi, Thanks for the responses. I've created a quick application (using one textbox and one button) to see if global variables are eating up memory and not releasing it, and that seems to be the case.
Public Class Form1 Dim globalString As String = "" Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged globalString = TextBox1.Text End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click TextBox1.Text = "" globalString = Nothing End Sub End Class
When I add text to the global variable, the memory starts to get eaten pretty quickly, but when I click the button to set the variable to Nothing, the memory still isn't released, but more memory is taken. Thanks, Mitch FWell, if that's true, that's one more reason not to use globals. However, I'd be inclined to suggest that your methods of watching memory usage are flawed. Do you watch the memory in the task manager ? That's not really accurate. Also, when I run this, the extra memory usage is minimal. Also, global is not a global, it's a member variable. To be the .NET equivelant of a global, it would need to be static. Based on the minimal memory usage in the test I just did, I think you're worried about nothing, and certainly should do some reading regarding how the garbage collector works.
Christian Graus Please read this if you don't understand the answer I've given you "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
-
Hi, I've narrowed down a memory leak in my application to a single Sub, however, I can't figure out what's doing it. Whenever this Sub is called (SelectedIndexChanged), my memory usage grows by ~100 kb and doesn't go down, according to Task Manager. Here's my code: Note: The following names are Global Variables: appSelPath appSelName appSelAlt appSelPos appSelID canEnable beenFound And yes, I need all of these variables as they are used in many other methods within my application.
Dim selectedText As String = "" If lbApps.SelectedItems.Count = 1 Then btnLaunch.Enabled = True pbSel.Image = ilApps.Images(lbApps.SelectedIndex + 1) 'lvApps.SelectedItems(0).ImageList.Images(selImg) selectedText = lbApps.SelectedItem.ToString btnLaunch.Text = "Launch " + selectedText btnMove.Text = strMoveText.Replace("|", selectedText) 'Add Application Routine If selectedText <> "Add Application..." Then 'set app selected path For i As Integer = 0 To appListing.Count - 1 Dim lineData() As String = appListing.Item(i).ToString.Split("|") If selectedText = lineData(0) Then appSelPath = lineData(1) appSelName = lineData(0) If lineData.Length = 3 Then If lineData(2) = "True" Then appSelAlt = True Else appSelAlt = False End If End If Array.Clear(lineData, 0, lineData.Length) lineData = Nothing Next Dim enableIt As Boolean = True ' Dim appPos As Integer = -10 For i As Integer = 0 To appLaunched.Count - 1 Dim lineData() As String = appLaunched.Item(i).ToString.Split("|") If lineData(1) <> "wait" Then If appSelName = lineData(0) Then enableIt = False If CInt(lineData(1)) > 0 Then appSelPos = CInt(lineData(1)) appSelID = CInt(lineData(2)) canEnable = True End If End If End If Array.Clear(lineD
Mitch F. wrote:
The following names are Global Variables
No, they are not. There are no global variables in VB.NET.
Mitch F. wrote:
my memory usage grows by ~100 kb and doesn't go down, according to Task Manager.
The Task Manager doesn't show how much memory your application uses, it shows how much memory the memory management has allocated. When memory is released back to the memory management, it doesn't get released to the system unless the system needs it.
Mitch F. wrote:
Array.Clear(lineData, 0, lineData.Length) lineData = Nothing
Doing things like that only uses CPU time, it doesn't release any memory earlier. Clearing the array is pointless. When the array is no longer used, the references that it contains are no longer concidered, so all the strings also counts as unused. Actually, clearing the array will keep it in memory longer than if you didn't. Setting a reference to Nothing only serves a purpose if you later in the code actually check for that Nothing value. Clearing references for the purpose of releasing memory has no effect at all.
Despite everything, the person most likely to be fooling you next is yourself.
-
Hi, Thanks for the responses. I've created a quick application (using one textbox and one button) to see if global variables are eating up memory and not releasing it, and that seems to be the case.
Public Class Form1 Dim globalString As String = "" Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged globalString = TextBox1.Text End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click TextBox1.Text = "" globalString = Nothing End Sub End Class
When I add text to the global variable, the memory starts to get eaten pretty quickly, but when I click the button to set the variable to Nothing, the memory still isn't released, but more memory is taken. Thanks, Mitch FTaskManager ais about the worst tool you can use to see how much memory your app is using. Why?? This is because TaskManager isn't showing you the memory your app is using. It's showing you how much memory is reserved by the .NET CLR Virtual Machine that is running your app. If your app releases managed memory back to the runtime, the runtime holds onto it (as seen by TaskManager) because it's not being released back to Windows. The runtime holds onto it to fill future requests for memory by your application faster. If Windows needs the memory back, the .NET CLR will release any it memorys it has in reserve back to Windows. If you really want to see how much memory your app is using, use the Performance Monitor and the .NET CLR counters to monitor your app. Task Manager isn't show you how much memory your app is REALLY using.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
2006, 2007