2012-05-25 12 views
11

Deseo ejecutar varias aplicaciones web REST dentro de un proceso Java para ahorrar memoria y escalar fácilmente con la ayuda de Akka. Me gustaría estimar cuánta memoria consume cada controlador de solicitud y detectar estos peligrosos para todo el sistema.Monitoreo del uso de memoria propia mediante la aplicación Java

  1. ¿Es posible controlar el uso de la memoria casi en tiempo real dentro de ese proceso y averiguar cuánta memoria se usa con cada controlador de solicitud? Lo que necesito para lograr eso? ¿Hay alguna herramienta?

  2. ¿Es posible atrapar out of memory exception y basarse en el uso de la memoria hacer algo, por ejemplo, bloquear solamente los controladores de solicitud que superen el límite de memoria asumido? Si es así, ¿qué podría ser malo con eso?

+1

Es una pregunta difícil. Vea más aquí: http://stackoverflow.com/questions/52353/in-java-what-is-the-best-way-to-determine-the-size-of-an-object – biziclop

Respuesta

4

Para responder a su primera pregunta, hay muchas herramientas que puede usar para controlar el uso de la memoria, sin embargo no conozco ninguna aplicación que asigne el uso de memoria a los hilos en tiempo "real". Dentro de la aplicación puede usar MemoryMXBean y MemoryPoolMXBeans para monitorear el uso de la memoria,

Para responder a su segunda pregunta: no, realmente no. Además del hecho de que generalmente es una mala idea atrapar a OOME, el problema principal es que el hilo que recibe la excepción puede no ser el verdadero culpable. el OOME se lanza en el hilo que hace la solicitud de asignación final. sin embargo, un poco de otro hilo podría ser el que llenó la mayor parte de la memoria. El otro problema es que, dado que OOME se puede lanzar en cualquier momento, podría ser arrojado dentro de algún código crítico dentro de su aplicación, dejándolo en un estado paralizado. En pocas palabras, usted casi siempre desea reiniciar su aplicación cuando recibe un OOME.

+0

Gracias por su respuesta. 1. ¿De modo que solo puedo asignar memoria a la secuencia? ¿No puedes hacer algo más sofisticado? 2. El problema de la fuente OOME que quería manejar en base a la información sobre el uso de la memoria, para poder saber si el problema está dentro de uno de mis controladores de solicitudes.Si no, podría escalar la excepción y reiniciar toda la JVM. ¿Sigue siendo una mala idea? –

+0

No estoy seguro de haber entendido nada en su comentario. 1. Como dije, no conozco ninguna solución para mapear el uso de memoria para enrutar programáticamente o en tiempo "real". 2. No entiendo lo que quieres decir. – jtahlborn

+0

Ach, no te he entendido bien. Supuse que es posible rastrear el uso de la memoria por componente individual y usar esta información mientras capturo a OOME (quién arrojó y cuánta memoria está usando cada componente) para determinar si un componente se puede matar de forma segura para el resto de ellos. –

2

Usted también puede agregar en sus instrucciones de código para controlar la memoria libre como:

Runtime runtime = Runtime.getRuntime(); 
System.out.println("Free memory: " + runtime.freeMemory() + " bytes."); 

No es posible manejar esta excepción. El problema es que si está ejecutando todos sus servicios web en un servidor de aplicaciones común (por ejemplo, tomcat), entonces si hay una excepción de "falta de memoria", JVM se desactivará. Intente ver si hay alguna pérdida de memoria o un mal manejo de memoria en su programa. Puede usar perfiles dentro de Netbeans o Eclipse. Además, el análisis del código con una herramienta como "findbugs" o "sonar" podría mostrarle posibles malas prácticas dentro de su código.

En cualquier caso, el uso de las opciones de Java relacionadas con la recolección de basura o la memoria JVM (como -Xmx) puede reducir dichas excepciones y mejorar el rendimiento.

+0

Una cosa importante a tener en cuenta cuando se utiliza Runtime.freeMemory() es que incluye basura actualmente en el montón y, por lo tanto, puede que no le proporcione exactamente lo que desea. –

+0

Precisamente, tienes razón. Gracias por el comentario. Sin embargo, podría ser indicativo en muchos casos de manejo incorrecto de la memoria. – stzoannos

7

La memoria total utilizada/libre de un programa se puede obtener en el programa a través de java.lang.Runtime.getRuntime();

El tiempo de ejecución tiene varios métodos que se relacionan con la memoria. El siguiente ejemplo de codificación demuestra su uso.

package test; 

import java.util.ArrayList; 
import java.util.List; 

public class PerformanceTest { 
    private static final long MEGABYTE = 1024L * 1024L; 

    public static long bytesToMegabytes(long bytes) { 
    return bytes/MEGABYTE; 
    } 

    public static void main(String[] args) { 
    // I assume you will know how to create a object Person yourself... 
    List<Person> list = new ArrayList<Person>(); 
    for (int i = 0; i <= 100000; i++) { 
     list.add(new Person("Jim", "Knopf")); 
    } 
    // Get the Java runtime 
    Runtime runtime = Runtime.getRuntime(); 
    // Run the garbage collector 
    runtime.gc(); 
    // Calculate the used memory 
    long memory = runtime.totalMemory() - runtime.freeMemory(); 
    System.out.println("Used memory is bytes: " + memory); 
    System.out.println("Used memory is megabytes: " 
     + bytesToMegabytes(memory)); 
    } 
} 
Cuestiones relacionadas