Memory Problem

G

Guest

I am using VS 2003 (VB.Net) on a PPC2003 SP2 device.

My main program is having memory problems encrypting large byte arrays that
are passed to/from a .Net webservice. When I create a 2nd byte array (for
the conversion) the memory is not freed up. Since we receive many of these
arrays, I eventually get an OutofMemoryException and the gc.GetTotalMemory
call shows I am increasing the memory by the expected amount. After
researching and playing with the garbage collector (gc.collect), my
assumption is that somehow my byte array is still in scope (though I don't
understand how). I have created a very small program to reproduce the
problem -- any help from this community would be greatly appreciated. The
program has a button that creates a new 5MB array and two textboxes that show
the gc.GetTotalMemory before and after the creation. Here is the code:
_________

Imports testmemory.Class1

Public Class Form1
Inherits System.Windows.Forms.Form
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents MainMenu1 As System.Windows.Forms.MainMenu

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
MyBase.Dispose(disposing)
End Sub

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Label1 As System.Windows.Forms.Label
Friend WithEvents Label2 As System.Windows.Forms.Label
Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
Friend WithEvents Button2 As System.Windows.Forms.Button
Private Sub InitializeComponent()
Me.MainMenu1 = New System.Windows.Forms.MainMenu
Me.Button1 = New System.Windows.Forms.Button
Me.Label1 = New System.Windows.Forms.Label
Me.Label2 = New System.Windows.Forms.Label
Me.TextBox1 = New System.Windows.Forms.TextBox
Me.TextBox2 = New System.Windows.Forms.TextBox
Me.Button2 = New System.Windows.Forms.Button
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(16, 192)
Me.Button1.Size = New System.Drawing.Size(64, 24)
Me.Button1.Text = "run test"
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(24, 32)
Me.Label1.Size = New System.Drawing.Size(64, 24)
Me.Label1.Text = "Before "
'
'Label2
'
Me.Label2.Location = New System.Drawing.Point(24, 72)
Me.Label2.Size = New System.Drawing.Size(56, 24)
Me.Label2.Text = "After"
'
'TextBox1
'
Me.TextBox1.Location = New System.Drawing.Point(88, 32)
Me.TextBox1.Size = New System.Drawing.Size(104, 22)
Me.TextBox1.Text = ""
'
'TextBox2
'
Me.TextBox2.Location = New System.Drawing.Point(88, 72)
Me.TextBox2.Size = New System.Drawing.Size(104, 22)
Me.TextBox2.Text = ""
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(80, 240)
Me.Button2.Size = New System.Drawing.Size(64, 24)
Me.Button2.Text = "End"
'
'Form1
'
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.TextBox2)
Me.Controls.Add(Me.TextBox1)
Me.Controls.Add(Me.Label2)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button1)
Me.Menu = Me.MainMenu1
Me.Text = "Form1"

End Sub

#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Me.TextBox1.Text = ""
Me.TextBox2.Text = ""
'run memory test
Me.TextBox1.Text = System.GC.GetTotalMemory(False).ToString
BeginTest()
Me.TextBox2.Text = System.GC.GetTotalMemory(False).ToString

End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
Me.Close()
End Sub
End Class


Public Class Class1

Friend Shared Sub BeginTest()
'Call routine to allocate memory

Try
Dim baTest() As Byte = New Byte() {1}

Callfunct(baTest)

Catch ex As OutOfMemoryException
MessageBox.Show("BeginTest: " & ex.ToString)

Catch ex As Exception
MessageBox.Show("BeginTest: " & ex.ToString)
End Try


End Sub

Friend Shared Function Callfunct(ByVal batest As Byte()) As Byte()

Try
Dim baConv() As Byte

ReDim baConv(5000000)

Catch ex As OutOfMemoryException
MessageBox.Show("Callfunct: " & ex.ToString)

Catch ex As Exception
MessageBox.Show("Callfunct: " & ex.ToString)
End Try

Return (batest)
End Function
End Class
____

Thanks again for your help!
Mike
 
D

Daniel Moth

ReDim baConv(5000000)
The obvious question: Is that much memory (>4.5MB) available on the target?

E.g. try in the WinCE emulator and in Settings>ControlPanel->System under
the Memory tab configure the available Program Memory and you can get the
same results (or not if you move it far to the left)

Programmatically try calling GlobalMemoryStatus to see how much memory is
free

Cheers
Daniel
 
G

Guest

Good question and thanks for the reply -- I should have included more info.
I am using a 64MB device -- and have been pinvoking GlobalMemoryStatusCE for
memory info. Here are some stats on the sample program with my first message:
* Available determined from AvailablePhysical returned from
GlobalMemoryStatusCE
** % Load from Memory Load returned from GlobalMemoryStatusCE

Before first run: ~36MB Available, 17% Load
After first allocation of array: ~31MB Avaialable, 29% Load
2nd allocation: ~26MB Available, 41% Load

Each time I see the 5MB array allocation reflected properly.
After the third -- I don't get an error (in my sample program below) and it
just repeats the 2nd allocation stats. My guess is the the garbage collector
is freeing up memory at this point -- but why does it not go back to the
~36MB before the first run? Net, net -- I believe I have plenty of memory --
the real question is --- why are my previous memory allocations not freeing
up? Any thoughts?
 
D

Daniel Moth

Sorry I am not observing the same results as you. I am testing with a
release version and while not connected to VS, I assume you are doing the
same. The before/after numbers are the same throughout.

On what device are you trying this and is it replicatable in the emulator?

In any case, make sure you have the latest SP3 installed:
http://wiki.opennetcf.org/ow.asp?CompactFrameworkFAQ/DeterminingVersion

For more info on GC metrics for your app try the performance counters
(follow the two links in the first paragraph):
http://www.danielmoth.com/Blog/2004/08/performance-statistics-for-netcf-apps.html

If you are still having troubles I suggest updating your sample as the
current one does not have the GlobalMemoryStatus calls you mentioned (and I
don't know what else).

Cheers
Daniel
 
G

Guest

You need to study how CE does memory management. Search MSDN for an article
called something like "Advanced memory management in CE" by Doug Boling.
Just becasue your device has 64MB of RAM avaiable doesn't mean you app get
access to it.

I also recommend the two exisiting GC blog entries out there available for
the CF GC specifically. I don't have directly links and am too lazy to get
them at the moment. Search my blog at blog.opennetcf.org/ctacke or Daniel's
blog and you'll find the appropriate links.

-Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top