Metro/Windows Phone 7

윈도우폰7 앱 메모리 사용량 보기

길버트리 2011. 2. 7. 17:11
메모리 사용량은 어떻게 아나?
 
아시는 분은 아시겠지만 윈도우폰7 메모리 사용량은
Microsoft.Phone.dll에 포함되어 있는 Microsoft.Phone.Info.DeviceExtendedProperties 클래스를 통해
 
long totalBytes = (long)Microsoft.Phone.Info.DeviceExtendedProperties.GetValue(“DeviceTotalMemory”);
 
이런 식으로 얻을 수 있습니다.
 
GetValue에 parameter로 전달할 수 있는 이름은 아래와 같습니다.
 
DeviceTotalMemory – 윈도우폰 전체 메모리
ApplicationCurrentMemoryUsage – 앱의 현재 메모리 사용량
ApplicationPeakMemoryUsage – 앱의 최고 메모리 사용량
 



MemoryUsageBox 메모리 사용량 표시하는 커스텀 컨트롤 만들어보기

MemoryUsageBox.cs 에서
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Phone.Info;

namespace HugeFlow.Phone.Controls
{
    /// 
    /// 메모리 사용량을 표시하는 컨트롤
    /// 
    [TemplatePart(Name = MemoryUsageBox.TotalMemoryTextName, Type = typeof(TextBlock))]
    [TemplatePart(Name = MemoryUsageBox.CurrentMemoryUsageTextName, Type = typeof(TextBlock))]
    [TemplatePart(Name = MemoryUsageBox.PeakMemoryUsageTextName, Type = typeof(TextBlock))]
    public class MemoryUsageBox : Control
    {
        #region 멤버들

        internal const string TotalMemoryTextName = "TotalMemoryText";
        internal TextBlock TotalMemoryText = null;

        internal const string CurrentMemoryUsageTextName = "CurrentMemoryUsageText";
        internal TextBlock CurrentMemoryUsageText = null;

        internal const string PeakMemoryUsageTextName = "PeakMemoryUsageText";
        internal TextBlock PeakMemoryUsageText = null;

        private DispatcherTimer _updateTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) };

        private const string TotalValueName = "DeviceTotalMemory";
        private const string CurrentValueName = "ApplicationCurrentMemoryUsage";
        private const string PeakValueName = "ApplicationPeakMemoryUsage";

        #endregion 멤버들

        #region 생성자들

        /// 
        /// 기본생성자
        /// 
        public MemoryUsageBox()
        {
            this.DefaultStyleKey = typeof(MemoryUsageBox);

            this.IsHitTestVisible = false;

            _updateTimer.Tick += new EventHandler(_updateTimer_Tick);
            Loaded += new RoutedEventHandler(MemoryUsageBox_Loaded);
            Unloaded += new RoutedEventHandler(MemoryUsageBox_Unloaded);
        }

        #endregion 생성자들

        #region 메서드들

        private void StopUpdate()
        {
            _updateTimer.Stop();
        }

        private void StartUpdate()
        {
            UpdateTexts();
            _updateTimer.Start();
        }

        private void UpdateTexts()
        {
            UpdateText(TotalMemoryText, MemoryUsageBox.TotalValueName);
            UpdateText(CurrentMemoryUsageText, MemoryUsageBox.CurrentValueName);
            UpdateText(PeakMemoryUsageText, MemoryUsageBox.PeakValueName);
        }

        private void UpdateText(TextBlock textBlock, string valueName)
        {
            if (textBlock != null)
            {
                textBlock.Text = string.Format("{0:F1}m", ToMegabytes((long)DeviceExtendedProperties.GetValue(valueName)));
            }
        }

        #endregion 메서드들


        #region 오버라이드들

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            TotalMemoryText = this.GetTemplateChild(MemoryUsageBox.TotalMemoryTextName) as TextBlock;
            CurrentMemoryUsageText = this.GetTemplateChild(MemoryUsageBox.CurrentMemoryUsageTextName) as TextBlock;
            PeakMemoryUsageText = this.GetTemplateChild(MemoryUsageBox.PeakMemoryUsageTextName) as TextBlock;
        }

        #endregion 오버라이드들

        #region 이벤트 핸들러들

        void MemoryUsageBox_Loaded(object sender, RoutedEventArgs e)
        {
            StartUpdate();
        }

        void MemoryUsageBox_Unloaded(object sender, RoutedEventArgs e)
        {
            StopUpdate();
        }

        void _updateTimer_Tick(object sender, EventArgs e)
        {
            UpdateTexts();
        }

        private const double MEGABYTE = 1024 * 1024;

        public double ToMegabytes(long bytes)
        {
            return (double)bytes / MEGABYTE;
        }

        #endregion 이벤트 핸들러들

    }
}

generic.xaml 에서

    


사용 예) 어떤 앱의 MainPage.xaml.cs에서 
// Constructor
public MainPage()
{
    InitializeComponent();

    UpdateTouchPlayModeToggle(Config.TouchPlayMode);

#if DEBUG
    LayoutRoot.Children.Add(new MemoryUsageBox());
#endif
}

스크린샷 - 그림의 상단을 주목해 주세요.