C# Windows CE .net 3.5 to checked the memory usage
Asked Answered
U

2

5

I'm a newbie in this place and starter with C# mobile. Now , I'm working on C# handheld device platform. So , I have some question to ask about how to get the memory usage. I have try GC.GetTotalMemory() and get the allocated memory that the GC used. But , Can I use this to estimated that how much my application was allocated the memory. I suppose that it may be but not actual correct. Then I've try google to searching for any reference or class or anything to use for checked the memory on windows CE but I've found only in another platform that not supported with the thing I'm doing.

Thanks in advance , Stoper


Apologize for that I gone away from this post.

I'm really thank you to anybody who've answer my question and watch on this post.

Now , I got all that I need by implement the "OpenNetCF" reference in my project.

Thanks again ;)

Undercroft answered 4/8, 2011 at 3:54 Comment(0)
E
6

According to the docs, GC.GetTotalMemory returns

A number that is the best available approximation of the number of bytes currently allocated in managed memory.

This is a bit misleading/confusing to some devs, especially those coming from a native world. It's going to tell you how much memory the GC has allocated internally but not what its actual allocation for the whole heap (i.e. allocated and unallocated managed memory) from the system is.

It also doesn't report native allocations. This can be huge if you use a lot of GDI objects (bitmaps, brushes, etc) as those have native memory allocations as well. In teh case of a Bitmap, it's managed footprint is actually much smaller than its native footprint.

If you're interested in your managed apps actual impact on the overall system resources, you need to query the OS and ask how much physical and virtual memory it has to get an actual feel for what's going on (I find GC.GetTotalMemory to be relatively useless in fact). P/Invoking GlobalMemoryStatus gives you what you want. MSDN contains an example.

Evaleen answered 4/8, 2011 at 5:9 Comment(5)
FYI I found GlobalMemoryStatus rather inaccurate on my Windows CE 6 device. The available virtual, available physical, and memory load values would jump around as I continued to load more images into memory. Sometimes the values would be higher then before the image was loaded, sometimes lower, even though I was loading images (all images were kept loaded).Homegrown
I doubt it's inaccurate - I've never seen a platform where it was. It's probably that you simply don't understand exactly what it means. The GC holds it's own heap, which may grow or shrink. To grow or shrink it may allocate or free memory from the OS. Those allocations may grab from physical or virtual depending on whether they are specifically commit pages, or if they are purely reserved. Memory allocation is not super simple, and the GC is adding another layer of complexity on top of it.Evaleen
If you want I can get you a dump of the output. I am not sure if there is something special in the OS, but I have a loop which loads images. Seemingly at random, the total available physical and virtual memory will jump up. This should be impossible unless things are being moved out of memory.Homegrown
The GC is likely freeing HBITMAP handles, which in turn frees the native blocks where the native bitmaps were, which frees physical memory, and potentially virtual memory depending on the location and what's around it.Evaleen
? but I can still use the images and display them on screen. The images are not being disposed, they are put into an array as part of a caching system.Homegrown
C
3

Try this. It will give you what I think you want, including what you had with GC.GetTotalMemory(). You would have to replace the text lables with your own or use it any way you want. You will have to use P/Invoke though...

public struct MEMORYSTATUS
{
    public UInt32 dwLength;
    public UInt32 dwMemoryLoad;
    public UInt32 dwTotalPhys;
    public UInt32 dwAvailPhys;
    public UInt32 dwTotalPageFile;
    public UInt32 dwAvailPageFile;
    public UInt32 dwTotalVirtual;
    public UInt32 dwAvailVirtual;
}

[DllImport("coredll.dll")]
private static extern void GlobalMemoryStatus(out MEMORYSTATUS lpBuffer);

public static void GetGlobalMemoryStatus(out UInt32 dwTotal, out UInt32 dwAvail,
                                             out UInt32 dwProcTotal, out UInt32 dwProcAvail)
{
    MEMORYSTATUS status = new MEMORYSTATUS();
    output.Length = (UInt32)System.Runtime.InteropServices.Marshal.SizeOf(output);
    GlobalMemoryStatus(out status);

    dwTotal = status.dwTotalPhys;
    dwAvail = status.dwAvailPhys;
    dwProcTotal = status.dwTotalVirtual;
    dwProcAvail = status.dwAvailVirtual;
}

private void UpdateMemoryDisplay()
{
    /*************************************************************************/
    bool IsTotalGB = false;
    bool IsUsedGB = false;
    uint TotalRamMemory;
    uint AvailRamMemory;
    uint ProcTotalRamMemory;
    uint ProcAvailRamMemory;

    GetGlobalMemoryStatus(out TotalRamMemory, out AvailRamMemory,
                          out ProcTotalRamMemory, out ProcAvailRamMemory);

    float TotalMB = (float)((float)TotalRamMemory / (1024 * 1024));
    float UsedMB = TotalMB - (float)((float)AvailRamMemory / (1024 * 1024));

    int RamPercent = (int)((UsedMB / TotalMB) * 100.0);

    if (1000 < TotalMB)
    {
        TotalMB /= 1000;
        IsTotalGB = true;
    }

    if (1000 < UsedMB)
    {
        UsedMB /= 1000;
        IsUsedGB = true;
    }

    this.RamMemMinLbl.Text = UsedMB.ToString("0.0") + ((false != IsUsedGB) ? "GB" : "MB");
    this.RamMemMaxLbl.Text = TotalMB.ToString("0.0") + ((false != IsTotalGB) ? "GB" : "MB");
    this.RamMemPercent.Current = RamPercent;

    IsUsedGB = false;

    TotalMB = (float)((float)ProcTotalRamMemory / (1024 * 1024));
    UsedMB = TotalMB - (float)((float)ProcAvailRamMemory / (1024 * 1024));

    if (1000 < UsedMB)
    {
        UsedMB /= 1000;
        IsUsedGB = true;
    }

    this.ProcRamMemMinLbl.Text = UsedMB.ToString("0.0") + ((false != IsUsedGB) ? "GB" : "MB");

    IsUsedGB = false;

    UsedMB = (float)((float)GC.GetTotalMemory(false) / (1024 * 1024));

    if (1000 < UsedMB)
    {
        UsedMB /= 1000;
        IsUsedGB = true;
    }

    this.GCMemMinLbl.Text = UsedMB.ToString("0.0") + ((false != IsUsedGB) ? "GB" : "MB");
    /*************************************************************************/
}
Crosslink answered 20/8, 2011 at 23:1 Comment(1)
Thanks for you all. Now , I've get the "OpenNETCF" reference. It's all what I want. But I still finding for how to get the application memory usage.Undercroft

© 2022 - 2024 — McMap. All rights reserved.