Memory/Resource Performance issue

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi,

Basically, I have developed an app to run on the .Net Compact framework (on
Pocket PC 2002) which among other things using SQL CE Replication, reads
other info in from various config files, creates each form dynamically (this
was part of the customer spec), and holds all the user entered info in a
single data class.

The problem I am seeing now though is that when the app is first started it
has a fast performance, and the forms are created and displayed very quickly.
However, after some time of using it, the app slows down noticeably to the
point where forms take up to 5 seconds to be displayed, and presumably the
back ground code is progressing slower too. In one effort, I tried manually
calling the GC.Collect command, but this did not make much/any difference.

The memory usage by looking in the Settings > Memory section isn’t too
horrific, although it does creep up the way without the OS reclaiming much
back. Having said that, our customer has reported on a couple of occasions
that the native Out of Memory dialog has been produced. I call dispose on
the SQLCEDataAdaptor, SQLCEConnection, and the SQLCEReplication after use as
I know these are fairly memory intensive – I also call dispose on the form
controls of a screen once that screen is finished with. Each screen is read
in on startup, and then I use data structures to hold the format of each
screen while the app is running. When a screen is about to be displayed I
read in this structure and create each required control. For reading in info
from flat config files, I use OpenNetCF’s Ayende:Configuration class.

Does anyone have any ideas of how to optimise an app, or come across this
sort of thing???

Thanks for your time!
 
Thanks Alex, I got the following data from the Performance Monitor - does
anything in here scream out?

Like I say, the app runs very quickly to begin with, but over time of use it
starts to slow down until it is very noticable.

Thanks!

counter value n mean min max
Execution Engine Startup Time 1107 0 0 0 0
Total Program Run Time 367357 0 0 0 0
Peak Bytes Allocated 2222131 0 0 0 0
Number Of Objects Allocated 129197 0 0 0 0
Bytes Allocated 7328300 129197 56 8 16836
Number Of Simple Collections 5 0 0 0 0
Bytes Collected By Simple Collection 3810980 5 762196 738268 812804
Bytes In Use After Simple Collection 2498592 5 499718 366540 595200
Time In Simple Collect 457 5 91 75 102
Number Of Compact Collections 4 0 0 0 0
Bytes Collected By Compact Collections 2713492 4 678373 618044 791544
Bytes In Use After Compact Collection 1425800 4 356450 168800 516292
Time In Compact Collect 554 4 138 98 173
Number Of Full Collections 1 0 0 0 0
Bytes Collected By Full Collection 207452 1 207452 207452 207452
Bytes In Use After Full Collection 571324 1 571324 571324 571324
Time In Full Collection 135 1 135 135 135
GC Number Of Application Induced Collections 0 0 0 0 0
GC Latency Time 1146 10 114 75 173
Bytes Jitted 219806 2019 108 1 21753
Native Bytes Jitted 519644 2019 257 20 38016
Number of Methods Jitted 2019 0 0 0 0
Bytes Pitched 1254 24 52 10 177
Number of Methods Pitched 24 0 0 0 0
Number of Exceptions 11 0 0 0 0
Number of Calls 1105092 0 0 0 0
Number of Virtual Calls 574134 0 0 0 0
Number Of Virtual Call Cache Hits 572908 0 0 0 0
Number of PInvoke Calls 76956 0 0 0 0
Total Bytes In Use After Collection 11156978 10 1115697 515800 1648719
 
Hi Alex,

Thanks for the reply. Thinking about it, I do use a number of Datasets
within the app which are not being disposed of when finished. From what i
have read, I am disposing of the SQL connection and dataadaptor objects
correctly, so the dataset stuff would fit in with what's happening. Also, is
it possible to manually dispose of my own data structures? They do not have
any parent classes, they are simply used to internally hold data that the app
requires at run time - how would i go about disposing of the local instances
of them when finished using an instance of a data class?

Thanks again,

Stuart
 
You don't need to "dispose" them specifically.
Just make sure that when you're done with an instance of your data structure
it's not referenced anywhere else to allow GC to collect it.

-Alex
 
Thanks for all the info! Much appreciated.
I'll add the dispose calls in for the datasets first thing monday morning -
as if these objects are not being cleared then that's going to keep hold of a
large chunk. Most of the data structures i use are called as local objects
within a function, so they should be getting cleared by GC? The largest one
though is created as a member object of one of my classes, and is present
right the way through the life of the app. It is also passed into other
classes as a reference, so that I only have one set of data within it, and
the object is updated by the processes in each class. It contains strings,
ints, and arraylists within it - although i do clear out the arraylists when
i want to clean the contents of the class.

Stuart
 
I see.. So you have an instance of your data structure class that's
maintained throughout the life of you app.
Even though it is a suggested way to imporove the performance of a CF app,
it does provent the GC collecting it.

Are you able to reproduce this "Out of memory" exception? If you're, you
could get the exact line throwing this,
catch this exception, try to free up some program memory (see my blog post
on that:
http://blog.opennetcf.org/ayakhnin/PermaLink.aspx?guid=f1df04aa-99c0-4e2a-906d-6fcf0c4b0d59)
and retry the memory allocation.

HTH... Alex
 
Hmm. At this moment in time, I have never had the out of memory exception,
only ever seen it once or twice on the customer's device. Even then, when i
tried to reproduce it I could not.

I'm back into the office now, so will attempt to introduce the other ideas
we talked about and see how it goes.

Thanks,
Stuart
 
Back
Top