Windows Phone 8 显示当前项目的使用内存,最大峰值,最大内存上限

时间:2021-01-03 15:59:41
public static class MemoryDiagnosticsHelper
{
public static bool isStart = false;
static Popup popup;
static TextBlock currentMemoryKB;
static TextBlock currentMemoryMB;
static TextBlock currentLumitMemoryMB;
static DispatcherTimer timer;
static bool forceGc;
const long MAX_MEMORY = 90 * 1024 * 1024; // 90MB, per marketplace
static int lastSafetyBand = -1; // to avoid needless changes of colour const long MAX_CHECKPOINTS = 10; // adjust as needed
static Queue<MemoryCheckpoint> recentCheckpoints; static bool alreadyFailedPeak = false; // to avoid endless Asserts /// <summary>
/// Starts the memory diagnostic timer and shows the counter
/// </summary>
/// <param name="timespan">The timespan between counter updates</param>
/// <param name="forceGc">Whether or not to force a GC before collecting memory stats</param>
[Conditional("DEBUG")]
public static void Start(TimeSpan timespan, bool forceGc)
{
isStart = true;
if (timer != null) throw new InvalidOperationException("Diagnostics already running"); MemoryDiagnosticsHelper.forceGc = forceGc;
recentCheckpoints = new Queue<MemoryCheckpoint>(); StartTimer(timespan);
ShowPopup();
} /// <summary>
/// Stops the timer and hides the counter
/// </summary>
[Conditional("DEBUG")]
public static void Stop()
{
isStart = false;
HidePopup();
StopTimer();
recentCheckpoints = null;
} /// <summary>
/// Add a checkpoint to the system to help diagnose failures. Ignored in retail mode
/// </summary>
/// <param name="text">Text to describe the most recent thing that happened</param>
[Conditional("DEBUG")]
public static void Checkpoint(string text)
{
if (recentCheckpoints == null) return;
if (recentCheckpoints.Count >= MAX_CHECKPOINTS - 1) recentCheckpoints.Dequeue();
recentCheckpoints.Enqueue(new MemoryCheckpoint(text, GetCurrentMemoryUsage()));
} /// <summary>
/// Recent checkpoints stored by the app; will always be empty in retail mode
/// </summary>
public static IEnumerable<MemoryCheckpoint> RecentCheckpoints
{
get
{
if (recentCheckpoints == null) yield break; foreach (MemoryCheckpoint checkpoint in recentCheckpoints) yield return checkpoint;
}
} /// <summary>
/// Gets the current memory usage, in bytes. Returns zero in non-debug mode
/// </summary>
/// <returns>Current usage</returns>
public static long GetCurrentMemoryUsage()
{
// don't use DeviceExtendedProperties for release builds (requires a capability)
return (long)DeviceExtendedProperties.GetValue("ApplicationCurrentMemoryUsage"); } /// <summary>
/// Gets the current memory usage, in bytes. Returns zero in non-debug mode
/// </summary>
/// <returns>Current usage</returns>
public static long GetCurrentPeakMemoryUsage()
{
// don't use DeviceExtendedProperties for release builds (requires a capability)
return (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage"); } /// <summary>
/// Gets the peak memory usage, in bytes. Returns zero in non-debug mode
/// </summary>
/// <returns>Peak memory usage</returns>
public static long GetPeakMemoryUsage()
{
// don't use DeviceExtendedProperties for release builds (requires a capability)
return (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage");
} /// <summary>
/// Gets the peak memory usage, in bytes. Returns zero in non-debug mode
/// </summary>
/// <returns>Peak memory usage</returns>
public static long GetLumitMemoryUsage()
{
// don't use DeviceExtendedProperties for release builds (requires a capability)
return (long)DeviceExtendedProperties.GetValue("ApplicationWorkingSetLimit");
} private static void ShowPopup()
{
popup = new Popup();
double fontSize = (double)Application.Current.Resources["PhoneFontSizeSmall"] - 2;
Brush foreground = (Brush)Application.Current.Resources["PhoneForegroundBrush"];
StackPanel sp = new StackPanel { Orientation = Orientation.Horizontal, Background = (Brush)Application.Current.Resources["PhoneSemitransparentBrush"] };
//currentMemoryKB = new TextBlock { Text = "---", FontSize = fontSize, Foreground = new SolidColorBrush(Colors.Red)};
//peakMemoryBlock = new TextBlock { Text = "", FontSize = fontSize, Foreground = new SolidColorBrush(Colors.White), Margin = new Thickness(5, 0, 0, 0) };
//sp.Children.Add(new TextBlock { Text = " kb", FontSize = fontSize, Foreground = foreground }); //sp.Children.Add(currentMemoryKB); currentMemoryMB = new TextBlock { Text = "---", FontSize = fontSize, Foreground = new SolidColorBrush(Colors.White) };
currentMemoryKB = new TextBlock { Text = "---", Margin = new Thickness(10, 0, 0, 0), FontSize = fontSize, Foreground = new SolidColorBrush(Colors.Red) };
currentLumitMemoryMB = new TextBlock { Text = "---", Margin = new Thickness(10, 0, 0, 0), FontSize = fontSize, Foreground = new SolidColorBrush(Colors.Green) };
sp.Children.Add(currentMemoryMB);
sp.Children.Add(currentMemoryKB);
sp.Children.Add(currentLumitMemoryMB); sp.RenderTransform = new CompositeTransform { Rotation = 0, TranslateX = 150, TranslateY = 0, CenterX = 0, CenterY = 0 };
popup.Child = sp;
popup.IsOpen = true;
} private static void StartTimer(TimeSpan timespan)
{
timer = new DispatcherTimer();
timer.Interval = timespan;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
} static void timer_Tick(object sender, EventArgs e)
{
if (forceGc) GC.Collect(); UpdateCurrentMemoryUsage();
UpdatePeakMemoryUsage(); } private static void UpdatePeakMemoryUsage()
{
if (alreadyFailedPeak) return; long peak = GetPeakMemoryUsage();
//if (peak >= MAX_MEMORY)
//{
// alreadyFailedPeak = true;
// Checkpoint("*MEMORY USAGE FAIL*");
// if (Debugger.IsAttached) Debug.Assert(false, "Peak memory condition violated");
//}
} private static void UpdateCurrentMemoryUsage()
{
try
{
long mem = GetCurrentMemoryUsage();
long feng = GetCurrentPeakMemoryUsage();
long lumit = GetLumitMemoryUsage();
currentMemoryKB.Text = string.Format("{0:f}", feng / 1024.0 / 1024.0) + "MB";
currentMemoryMB.Text = string.Format("{0:f}", mem / 1024.0 / 1024.0) + "MB";
currentLumitMemoryMB.Text = string.Format("{0:f}", lumit / 1024.0 / 1024.0) + "MB";
}
catch { }
//int safetyBand = GetSafetyBand(mem);
//if (safetyBand != lastSafetyBand)
//{
// currentMemoryKB.Foreground = GetBrushForSafetyBand(safetyBand);
// lastSafetyBand = safetyBand;
//}
} private static Brush GetBrushForSafetyBand(int safetyBand)
{
return new SolidColorBrush(Colors.Red);
//switch (safetyBand)
//{
// case 0:
// return new SolidColorBrush(Colors.Green); // case 1:
// return new SolidColorBrush(Colors.Orange); // default:
// return new SolidColorBrush(Colors.Red);
//}
} private static int GetSafetyBand(long mem)
{
double percent = (double)mem / (double)MAX_MEMORY;
if (percent <= 0.75) return 0; if (percent <= 0.90) return 1; return 2;
} private static void StopTimer()
{
timer.Stop();
timer = null;
} private static void HidePopup()
{
popup.IsOpen = false;
popup = null;
}
} /// <summary>
/// Holds checkpoint information for diagnosing memory usage
/// </summary>
public class MemoryCheckpoint
{
/// <summary>
/// Creates a new instance
/// </summary>
/// <param name="text">Text for the checkpoint</param>
/// <param name="memoryUsage">Memory usage at the time of the checkpoint</param>
internal MemoryCheckpoint(string text, long memoryUsage)
{
Text = text;
MemoryUsage = memoryUsage;
} /// <summary>
/// The text associated with this checkpoint
/// </summary>
public string Text { get; private set; } /// <summary>
/// The memory usage at the time of the checkpoint
/// </summary>
public long MemoryUsage { get; private set; }
}
调用方式:
 MemoryDiagnosticsHelper.Start(TimeSpan.FromMilliseconds(500), true);