С# Windows CE .net 3.5 для проверки использования памяти

Я новичок в этом месте и начинаю с мобильного С#. Сейчас я работаю над платформой портативных устройств С#. Итак, у меня есть вопрос о том, как получить использование памяти. Я попробовал GC.GetTotalMemory() и получил выделенную память, которую использовал GC. Но могу ли я использовать это, чтобы оценить, сколько памяти было выделено моему приложению. Я предполагаю, что это может быть, но не совсем правильно. Затем я попытался найти в Google любую ссылку, класс или что-либо, что можно использовать для проверки памяти в Windows CE, но я нашел только на другой платформе, которая не поддерживается тем, что я делаю.

Заранее спасибо, Стопер


Извините за то, что я ушел из этого поста.

Я действительно благодарю всех, кто ответил на мой вопрос и посмотрел этот пост.

Теперь я получил все, что мне нужно, внедрив ссылку «OpenNetCF» в свой проект.

Спасибо еще раз ;)


person Sathapanic Sriprom    schedule 04.08.2011    source источник


Ответы (2)


Согласно документам, GC.GetTotalMemory возвращает

Число, которое является наилучшей доступной аппроксимацией количества байтов, выделенных в настоящее время в управляемой памяти.

Это немного вводит в заблуждение/сбивает с толку некоторых разработчиков, особенно тех, кто пришел из родного мира. Он расскажет вам, сколько памяти выделил GC внутренне, но не каково его фактическое выделение для всей кучи (т.е. выделенная и нераспределенная управляемая память) из системы.

Он также не сообщает о собственных выделениях. Это может быть огромным, если вы используете много объектов GDI (растровые изображения, кисти и т. д.), поскольку они также имеют собственное распределение памяти. В случае растрового изображения его управляемая площадь на самом деле намного меньше, чем его исходная площадь.

Если вас интересует фактическое влияние ваших управляемых приложений на общие системные ресурсы, вам нужно запросить ОС и узнать, сколько у нее физической и виртуальной памяти, чтобы получить реальное представление о том, что происходит ( Я считаю, что GC.GetTotalMemory на самом деле относительно бесполезен). P/Invoking GlobalMemoryStatus дает вам то, что вы хотите. MSDN содержит пример.

person ctacke    schedule 04.08.2011
comment
К вашему сведению, я нашел GlobalMemoryStatus довольно неточным на моем устройстве с Windows CE 6. Доступные виртуальные, доступные физические значения и значения загрузки памяти прыгали по мере того, как я продолжал загружать в память больше изображений. Иногда значения были выше, чем до загрузки изображения, иногда ниже, даже если я загружал изображения (все изображения оставались загруженными). - person Trisped; 08.02.2013
comment
Я сомневаюсь, что это неточно - я никогда не видел платформу, где это было. Скорее всего, вы просто не понимаете, что это значит. GC содержит собственную кучу, которая может увеличиваться или уменьшаться. Чтобы увеличить или уменьшить его, может выделяться или освобождаться память операционной системы. Эти выделения могут быть получены из физического или виртуального пространства в зависимости от того, являются ли они специально зафиксированными страницами или полностью зарезервированы. Распределение памяти не так просто, и сборщик мусора добавляет к этому еще один уровень сложности. - person ctacke; 08.02.2013
comment
Если хотите, я могу дать вам дамп вывода. Я не уверен, что в ОС есть что-то особенное, но у меня есть цикл, который загружает изображения. По-видимому, случайно подскочит общая доступная физическая и виртуальная память. Это должно быть невозможно, если вещи не перемещаются из памяти. - person Trisped; 10.02.2013
comment
Сборщик мусора, вероятно, освобождает дескрипторы HBITMAP, что, в свою очередь, освобождает собственные блоки, где находились собственные растровые изображения, что освобождает физическую память и, возможно, виртуальную память в зависимости от местоположения и того, что вокруг него. - person ctacke; 10.02.2013
comment
? но я все еще могу использовать изображения и отображать их на экране. Изображения не удаляются, они помещаются в массив как часть системы кэширования. - person Trisped; 12.02.2013

Попробуй это. Это даст вам то, что, я думаю, вы хотите, включая то, что у вас было с GC.GetTotalMemory(). Вам придется заменить текстовые метки своими собственными или использовать их по своему усмотрению. Однако вам придется использовать P/Invoke...

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");
    /*************************************************************************/
}
person CCS    schedule 20.08.2011
comment
Спасибо за вас всех. Теперь у меня есть ссылка на OpenNETCF. Это все, что я хочу. Но я все еще нахожу, как получить использование памяти приложения. - person Sathapanic Sriprom; 27.08.2011