Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WinCE上运行我的应用程序之前,如何分配程序内存和存储?_C#_Winforms_Memory Management_Windows Ce - Fatal编程技术网

C# 在WinCE上运行我的应用程序之前,如何分配程序内存和存储?

C# 在WinCE上运行我的应用程序之前,如何分配程序内存和存储?,c#,winforms,memory-management,windows-ce,C#,Winforms,Memory Management,Windows Ce,我正在用C语言重新编程一个应用程序,以便在Windows CE上运行,但是,我的机器内存不足。 所以我需要分配适当数量的程序内存和存储内存。但是我不能在每次重新启动时手动分配它,然后我找到了SetSystemMemoryDivision函数。 我制作的分配代码基本上如下所示: public void setmemory() { //Checks if the memory is correctly allocated while (storage

我正在用C语言重新编程一个应用程序,以便在Windows CE上运行,但是,我的机器内存不足。 所以我需要分配适当数量的程序内存和存储内存。但是我不能在每次重新启动时手动分配它,然后我找到了SetSystemMemoryDivision函数。 我制作的分配代码基本上如下所示:

    public void setmemory()
    {
        //Checks if the memory is correctly allocated 
        while (storage_page != 800)
        {
            //Set the memory to 800 pages of 4096 bytes each ( = 800 * 4kB 3.200Kb )
            storage_page = 800;

            //Writes the seted memory
            SetSystemMemoryDivision(storage_page);

            Thread.Sleep(200);

            //Read system memory
            GetSystemMemoryDivision(ref storage_page, ref ram_page, ref page_size);
        }
    }     
    callmenu();
该功能正在运行,但如果我之前没有手动分配可接受的内存值,我的应用程序仍然会冻结机器。 如何确保在运行任何可以停止机器的进程之前分配内存?更正如下:


我在这个问题上错了。真正的应用程序只有在我的设备与计算机连接并通过VisualStudio运行调试后才能运行。每次我重新启动设备并尝试在pc上运行应用程序而不进行调试时,系统都会停止。即使我手动分配内存。因此,系统似乎冻结了,因为程序试图分配超过可用32MB的内存。

这是一个困难的挑战。首先,你需要知道你的应用程序运行需要多少内存。知道这一点的唯一方法就是不断地测试。然后加上一笔应急金额

一旦你有了这个号码,你可以在应用程序启动的很早就调用SetSystemMemoryDivision,在它开始在堆上分配很多东西并耗尽内存之前。在静态void Main的早期,在调用应用程序之前。Run将是典型的候选位置

如果所需的内存量未知,则始终可以创建一个后台服务线程,定期检查可用内存并重新调整内存分区,以便始终为GC堆留出空间。这更难实现,但并非不可能

下面是一个示例计时器进程,我使用它将内存保持在可用内存的95%,它将作为一个整数(如95)存储在HoldProgramMemoryPercent中:

    private void TimerProc(object state)
    {
        // check and adjust memory
        var total = MemoryManagement.SystemProgramMemory + MemoryManagement.SystemStorageMemory;

        var before = (MemoryManagement.SystemProgramMemory / (float)total) * 100;

        var requiredStorage = (int)(((100 - HoldProgramMemoryPercent) / 100f) * total);
        if ((requiredStorage != m_lastLevel) && (requiredStorage != MemoryManagement.SystemStorageMemory))
        {
            MemoryManagement.SystemStorageMemory = requiredStorage;

            var after = (MemoryManagement.SystemProgramMemory / (float)total) * 100;

            Debug.WriteLine(string.Format("Program memory changed from {0}% to {1}%", before, after));

            m_lastLevel = requiredStorage;
        }

        Debug.WriteLine(string.Format("Memory load is at {0}%", MemoryManagement.MemoryLoad));
    }

这是一个困难的挑战。首先,你需要知道你的应用程序运行需要多少内存。知道这一点的唯一方法就是不断地测试。然后加上一笔应急金额

一旦你有了这个号码,你可以在应用程序启动的很早就调用SetSystemMemoryDivision,在它开始在堆上分配很多东西并耗尽内存之前。在静态void Main的早期,在调用应用程序之前。Run将是典型的候选位置

如果所需的内存量未知,则始终可以创建一个后台服务线程,定期检查可用内存并重新调整内存分区,以便始终为GC堆留出空间。这更难实现,但并非不可能

下面是一个示例计时器进程,我使用它将内存保持在可用内存的95%,它将作为一个整数(如95)存储在HoldProgramMemoryPercent中:

    private void TimerProc(object state)
    {
        // check and adjust memory
        var total = MemoryManagement.SystemProgramMemory + MemoryManagement.SystemStorageMemory;

        var before = (MemoryManagement.SystemProgramMemory / (float)total) * 100;

        var requiredStorage = (int)(((100 - HoldProgramMemoryPercent) / 100f) * total);
        if ((requiredStorage != m_lastLevel) && (requiredStorage != MemoryManagement.SystemStorageMemory))
        {
            MemoryManagement.SystemStorageMemory = requiredStorage;

            var after = (MemoryManagement.SystemProgramMemory / (float)total) * 100;

            Debug.WriteLine(string.Format("Program memory changed from {0}% to {1}%", before, after));

            m_lastLevel = requiredStorage;
        }

        Debug.WriteLine(string.Format("Memory load is at {0}%", MemoryManagement.MemoryLoad));
    }
问题解决了

主要问题是CF2.0的GC无法正确管理收集。 随着机器和项目中的NETCFV2.0升级到v3.5,GC开始正确管理collect,应用程序运行良好

感谢所有试图帮助我的人,我希望我能帮助有类似问题的人。

问题解决了

主要问题是CF2.0的GC无法正确管理收集。 随着机器和项目中的NETCFV2.0升级到v3.5,GC开始正确管理collect,应用程序运行良好

感谢所有试图帮助我的人,我希望我能帮助有类似问题的人。

使用此代码。 作为参数存储器的int值比率

[DllImport("coredll.dll")]
        private static extern int GetSystemMemoryDivision(ref int lpdwStorePages, ref int ldpwRamPages, ref int ldpwPageSize);
        [DllImport("coredll.dll")]
        private static extern int SetSystemMemoryDivision(int dwStorePages);
 public static void SetMemory(int division)
        {
            int storePages = 0;
            int ramPages = 0;
            int pageSize = 0;
            int totalPages = 0;
            if (GetSystemMemoryDivision(ref storePages, ref ramPages, ref pageSize) == 1)
            {
                totalPages = storePages + ramPages;
                storePages = Convert.ToInt32(totalPages * (100 - division) / 100);
                SetSystemMemoryDivision(storePages);
            }
        }
使用此代码。 作为参数存储器的int值比率

[DllImport("coredll.dll")]
        private static extern int GetSystemMemoryDivision(ref int lpdwStorePages, ref int ldpwRamPages, ref int ldpwPageSize);
        [DllImport("coredll.dll")]
        private static extern int SetSystemMemoryDivision(int dwStorePages);
 public static void SetMemory(int division)
        {
            int storePages = 0;
            int ramPages = 0;
            int pageSize = 0;
            int totalPages = 0;
            if (GetSystemMemoryDivision(ref storePages, ref ramPages, ref pageSize) == 1)
            {
                totalPages = storePages + ramPages;
                storePages = Convert.ToInt32(totalPages * (100 - division) / 100);
                SetSystemMemoryDivision(storePages);
            }
        }

谢谢,克塔克。我已经将函数移到“static void Main”中“Application.Run”之前的程序类中,但它仍然没有运行。类似于示例的自动分配应该在第一组之后运行,对吗?在这种情况下,可能是系统中的当前应用程序内存太小,无法加载.NET CF运行时。您是否尝试运行简单的hello world应用程序而不是完整的应用程序?它有用吗?如果是这样的话,我唯一能想象的是,在进入Main之前,您有一些全局对象被初始化,这些对象在启动时分配了大量内存。在调用SetSystemMemoryDivision之后,您可以简单地尝试在Main中分配它们,而不是将它们声明并初始化为全局变量。谢谢,Valter。较小的应用程序运行良好,但在SetSystemMemoryDivision之前,我不会初始化任何对象。运行此函数之前的唯一调用是DLL和必要的变量。我尝试过不同数量的内存分配,但都不起作用。重要的是要注意,如果我手动分配相同的内存量,它会起作用
如果它是手动工作的,而不是编程工作的,那么您的API调用可能会失败。您应该能够创建一个只设置内存分区的应用程序,运行该应用程序,然后转到控制面板,分区滑块应该已经移动。根据这些文档,您调用了一个完全不检查返回值的函数,当成功调用时,返回值SYSMEM\u已更改。谢谢,ctacke。我已经将函数移到“static void Main”中“Application.Run”之前的程序类中,但它仍然没有运行。类似于示例的自动分配应该在第一组之后运行,对吗?在这种情况下,可能是系统中的当前应用程序内存太小,无法加载.NET CF运行时。您是否尝试运行简单的hello world应用程序而不是完整的应用程序?它有用吗?如果是这样的话,我唯一能想象的是,在进入Main之前,您有一些全局对象被初始化,这些对象在启动时分配了大量内存。在调用SetSystemMemoryDivision之后,您可以简单地尝试在Main中分配它们,而不是将它们声明并初始化为全局变量。谢谢,Valter。较小的应用程序运行良好,但在SetSystemMemoryDivision之前,我不会初始化任何对象。运行此函数之前的唯一调用是DLL和必要的变量。我尝试了不同数量的内存分配,但都不起作用。值得注意的是,如果我手动分配相同数量的内存,效果会很好。如果是手动分配,但不是以编程方式分配,那么您的API调用可能会失败。您应该能够创建一个只设置内存分区的应用程序,运行该应用程序,然后转到控制面板,分区滑块应该已经移动。根据这些文档,您可以调用它,但在成功调用时根本不检查返回值,因为返回SYSMEM_已更改。