zoukankan      html  css  js  c++  java
  • Windows Phone 内存检测方法

          在 VS 的开发环境中,有内存性能分析的工具(VS 的菜单栏——> 调试——> 启动 Windows Phone性能分析)

    可以分析应用的内存占用情况,但是通常只有在程序停止运行结束后,我们才能看到数据。但是有时候我们想在程序

    运行过程中时事看到内存占用情况,比如在执行某个特定的方法后获取内存信息。这里我写了一个简单的方法,在程序

    运行时,每隔四秒就把内存信息打印到屏幕上,为了在应用的所有页面都可以检查,我们使用之前写过的一个自定义 Toast

    输出框(文章和代码工程)。

       

          首先在页面的构造函数中,初始化一个 计时器:

                // 初始化计时器,每隔四秒钟就打印当前应用所占内存、峰值、和设备总内存
                dispacherTimer = new System.Windows.Threading.DispatcherTimer();
                dispacherTimer.Interval = TimeSpan.FromSeconds(4);
                dispacherTimer.Tick += new EventHandler(dispacherTimer_Tick);

    定义定时器调用的方法:

            #region 内存使用情况
            static string total = "DeviceTotalMemory";
            static string current = "ApplicationCurrentMemoryUsage";
            static string peak = "ApplicationPeakMemoryUsage";
    
            static long totlaBytes;
            static long currentBytes;
            static long peakBytes;
    
            static System.Windows.Threading.DispatcherTimer dispacherTimer;
           
            void dispacherTimer_Tick(object sender, EventArgs e)
            {
                // 获取设备的总内存
                totlaBytes = (long)Microsoft.Phone.Info.DeviceExtendedProperties.GetValue(total);
    
                // 获取应用当前占用内存
                currentBytes = (long)Microsoft.Phone.Info.DeviceExtendedProperties.GetValue(current);
    
                // 获取内存占用的峰值
                peakBytes = (long)Microsoft.Phone.Info.DeviceExtendedProperties.GetValue(peak);
                
                // 使用自定义的 MyDialog 控件打印出来
                MyDialog.ShowToastMessage(string.Format("当前:{0:F2}MB;  峰值:{1:F2}MB;  总:{2:F2}MB;", currentBytes / (1024 * 1024.0), peakBytes / (1024 * 1024.0), totlaBytes / (1024 * 1024.0)));
            }
            #endregion

    在xaml 页面中添加两个按钮,分别用来启动和关闭内存信息检测,相应的 C# 函数:

            // 取消内存信息打印,释放资源
            private void btnStop_Click(object sender, RoutedEventArgs e)
            {
                dispacherTimer.Stop();
                dispacherTimer.Tick -= new EventHandler(dispacherTimer_Tick);
                dispacherTimer = null;
            }
    
            // 开始向屏幕输出内存情况
            private void btnStart_Click(object sender, RoutedEventArgs e)
            {
                if (dispacherTimer != null)
                {
                    dispacherTimer.Start();
                }
            }

    显示截图:

        内存占用的问题在 WP 的开发中是比较棘手的。因为市面上的 Lumia系列的手机,很多都是一体机,无论是

    800 还是 920,它们在运行应用时,如果你的应用持续占用超过 120MB 的内存,那么它的发热情况是非常明显

    的。而且导致发热的问题主要是内存的问题,并非 CPU 消耗的问题,而且在传统的 Silverlight 应用中,相对于

    游戏应用,使用的数学运算等等消耗 CPU 的资源往往是微不足道的。

        我在开发过程中,总结了内存占用的一些情况,其中最主要的是在页面中绘制的元素太多,或者页面的显示尺寸太

    大,比如在一个 ListBox 中显示新闻,屏幕的高度是 800px,每屏显示 4条新闻,如果当前 ListBox 中共有24 条新闻,

    那么该 ListBox 就是 6 屏 X 800px = 4800 px  的高度 !!!如果这 24条全部显示在页面中,内存占用是 60MB,

    但是用户看到的有效信息只是屏幕中显示的 4条。所以把 ListBox 换成 LongListSelector (支持虚拟化和内存复用)

    是很有必要的。如果想继续使用 ListBox 可以写一个算法(曾经写过),就是ListBox 只显示当前四条的新闻,其它

    20条的新闻可以把它们的 Visibility 设置为 System.Windows.Visibility.Collapsed,当用户的手指划到那条新闻时,

    再把那条新闻的该属性设置为  System.Windows.Visibility.Visible, 这样如果全部显示 24条新闻占用 60MB,那么

    通过这个算法,内存只需要 25MB 左右。

          通常导致内存增加,可能是程序中一些不再使用的对象得不到有效的释放,这些对象越来越多,从而导致内存泄露,

    可能的原因:

    1)静态对象的引用

    2)事件没有与方法解除订阅

    3)静态事件没有与方法解除订阅

    4)非托管资源(实现了 IDispose 接口),没有调用 Dispose 方法

    5)非托管资源的 Dispose 方法没有执行完成

          另一个问题是,有的开发者在开放 WP8 的过程中,担心使用 async 和 await 关键字过多,会不会导致系统频繁创建

    额外的线程过多,结果消耗很多系统资源。其实并非如此,因为在 .net 4.5 中引入的 async 和 await 关键字只是简化了

    .net 4.0 中 Task 的创建和维护,通过使用同步编程的方式实现了异步线程的调用,并且 Task 在异步调用时,底层并非

    创建了新的线程,而是使用的线程池技术,达到线程复用的目的。所以在 WP8 的开发中,尽可能的使用 async 和 await

    因为它们不会增加应用过多占用系统的资源。

          最后还有一点建议,就是在程序开发的时候,比如在应用中需要显示网页内容,一个选择是在应用中放一个 WebBrowser

    控件,除非迫不得已,否则尽可能调用  Microsoft.Phone.Tasks.WebBrowserTask, 从而使用系统的 IE 浏览器打开网页内容

    ,因为 WebBrowser 控件显示网页内容时,所占用的内存也是相当大的,而且使用 IE 打开网页内容,不但系统会优化系统

    资源,而且它所占用的内存并不会算入到应用占用的内存中去。

            同理,相对于调用摄像头的 API(高级捕获 PhotoCaptureDevice 和 PhotoCamera ),最好使用系统任务:

    Microsoft.Phone.Tasks.CameraCaptureTask。

  • 相关阅读:
    几个论坛上看到的2015小米笔试题
    Line(扩展欧几里得)
    MapReduce编程之倒排索引
    annotation(@Retention@Target)详解
    【JEECG技术文档】JEECG平台对外接口JWT应用文档V3.7.2
    jeecg 模糊查询
    jeecg下实现自动默认模糊查询
    The packaging for this project did not assign a file to the build artifact
    Maven添加本地Jar包
    maven 如何引入本地jar包
  • 原文地址:https://www.cnblogs.com/hebeiDGL/p/3102978.html
Copyright © 2011-2022 走看看