[Tips and Tricks] Windows Phone. DeviceStatus. Uso de memoria

Introducción

Por encima de cuidar detalles como la
funcionalidad o la estética de nuestra aplicación, tenemos que lograr un
objetivo que parece simple pero que a veces se escapa, nuestra
aplicación debe funcionar correctamente bajo todas las condiciones en
todos los dispositivos para la que sea lanzada. Un fallo comun suele ser
que se escape la gestión de memoria de la aplicación pudiendo obtener una excepción de tipo OutOfMemoryException. Ya vimos como el control MemoryCounter del Coding4Fun Toolkit nos ayuda a saber el uso de memoria en todo momento. También tenemos disponible la herramienta Windows Phone Performance Analysis
para poder analizar el uso de memoria de nuestra aplicación entre otras
opciones. Sin embargo, el propio SDK nos incluye la posibilidad de
saber el uso de memoria de nuestra aplicación e incluso el límite máximo
de uso de memoria o la memoria disponible del dispositivo. Vamos a
aprender como realizar esta tarea en este artículo.

Monitorear la memoria

Tenemos disponible en el SDK de Windows Phone la API DeviceStatus
que nos permite obtener información del hardware del dispositivo como
la cantidad de memoria o la versión del sistema por ejemplo. Además,
tenemos disponible una serie de eventos a los que podemos suscribirnos
para recibir una notificación cuando un parámetro del sistema cambia.

Vamos a realizar un ejemplo práctico donde utilizar la API DeviceStatus. Creamos un nuevo proyecto:

La plantilla seleccionada será “Windows Phone Application
para simplificar al máximo el ejemplo. Comenzamos creando la base de
nuestra interfaz. Añadiremos dos botones, uno para aumentar el consumo
de memoria y otro para liberarla:

<Button Content="Aumenta consumo memoria"/>
<Button Content="Libera consumo memoria"/>

Añadimos sus eventos clic:

<Button Content="Aumenta consumo memoria" Click="AumentaMemoria_Click" />
<Button Content="Libera consumo memoria" Click="LiberaMemoria_Click"/>

Y en el code-behind:

private void AumentaMemoria_Click(object sender, RoutedEventArgs e)
{

}

private void LiberaMemoria_Click(object sender, RoutedEventArgs e)
{

}

Creamos una colección de Bytes para cargar en memoria:

List<Byte[]> _memoria;

En el primer botón añadimos 10MB al uso de memoria cada vez que sea
pulsado. En el segundo, limpiamos la colección y llamamos el recolector
de basura:

private void AumentaMemoria_Click(object sender, RoutedEventArgs e)
{
_memoria.Add(new Byte[1024 * 1024 * 10]);
}

private void LiberaMemoria_Click(object sender, RoutedEventArgs e)
{
_memoria.Clear();
GC.Collect();
}

Hasta aqui todo lo necesario para poder probar la memoria, podemos
aumentarla y liberarla. Sin embargo, no tenemos ahora mismo posibilidad
de saber que consumo esta realizando la aplicación. Vamos a añadir en
nuestra interfaz un TextBlock donde mostrar la información relacionada
con el uso de memoria:

Vamos a crear un método que actualice el texto del TextBlock anterior
con la información relacionada con la memoria. Dentro del método
usaremos la API DeviceStatus para acceder a ciertas propiedades
relacionadas con la memoria. Las propiedades son:

private void ActualizarDatos()
{
Data.Text = String.Format(@"
Actual: {0}MB
Pico máximo: {1}MB
Límite de uso: {2}MB
Total dispositivo: {3}MB",
(DeviceStatus.ApplicationCurrentMemoryUsage / 1000000).ToString(CultureInfo.InvariantCulture),
(DeviceStatus.ApplicationPeakMemoryUsage / 1000000).ToString(CultureInfo.InvariantCulture),
(DeviceStatus.ApplicationMemoryUsageLimit / 1000000).ToString(CultureInfo.InvariantCulture),
(DeviceStatus.DeviceTotalMemory / 1000000).ToString(CultureInfo.InvariantCulture));
}

Para finalizar llamaremos al método en los clic de los botones para
actualizar los valores en pantalla cada vez que pulsemos uno de ellos:

ActualizarDatos();

Sin duda una forma sencilla para poder consultar el uso de memoria. Sin
embargo, no es práctico en nuestras aplicaciones mostrar la información
en pantalla. Para solventar esa situación, podemos realizar un sencillo
Helper, llamado MemoryHelper, que contenga un método
que obtendrá la misma información cada X segundos y las mostrará en la
ventana de Output de Visual Studio:

public static void GetMemoryData(int seconds)
{
_timer = new Timer(state =>
{
string result = string.Empty;
result += String.Format(@"
Fecha: {0}
Actual: {1}MB
Pico máximo: {2}MB
Límite de uso: {3}MB
Total dispositivo: {4}MB",
DateTime.Now.ToLongTimeString(),
(DeviceStatus.ApplicationCurrentMemoryUsage / 1000000).ToString(CultureInfo.InvariantCulture),
(DeviceStatus.ApplicationPeakMemoryUsage / 1000000).ToString(CultureInfo.InvariantCulture),
(DeviceStatus.ApplicationMemoryUsageLimit / 1000000).ToString(CultureInfo.InvariantCulture),
(DeviceStatus.DeviceTotalMemory / 1000000).ToString(CultureInfo.InvariantCulture));

Deployment.Current.Dispatcher.BeginInvoke(() => Debug.WriteLine(result));
},
null,
TimeSpan.FromSeconds(seconds),
TimeSpan.FromSeconds(seconds));
}

Podéis descargar el ejemplo a continuación:


Más información

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *