2009-11-18 3 views
17

Je cherche un exemple de code Java JMX pour accéder aux valeurs des attributs JMX d'une autre machine virtuelle.Comment accéder à l'utilisation de la mémoire par programmation via JMX?

Avec JConsole, je n'ai aucun problème regarder java.lang/mémoire/Attributs/HeapMemory

Comment puis-je obtenir les mêmes informations d'un programme Java en cours d'exécution dans une machine virtuelle? Des exemples de toutes les options de ligne de commande nécessaires ou d'autres choses qui doivent être démarrées appréciées.

Répondre

17

Vous devez configurer un connecteur JMX. Voici un extrait de code qui obtiendra l'utilisation de la mémoire de tas engagée sur une machine distante.

String host ="myHost"; 
int port = 1234; 
HashMap map = new HashMap(); 
String[] credentials = new String[2]; 
credentials[0] = user; 
credentials[1] = password; 
map.put("jmx.remote.credentials", credentials); 
JMXConnector c = JMXConnectorFactory.newJMXConnector(createConnectionURL(host, port), map); 
c.connect(); 
Object o = c.getMBeanServerConnection().getAttribute(new ObjectName("java.lang:type=Memory"), "HeapMemoryUsage"); 
CompositeData cd = (CompositeData) o; 
System.out.println(cd.get("committed")); 

private static JMXServiceURL createConnectionURL(String host, int port) throws MalformedURLException 
{ 
    return new JMXServiceURL("rmi", "", 0, "/jndi/rmi://" + host + ":" + port + "/jmxrmi"); 
} 

Si vous ne vous souciez pas de la sécurité, vous pouvez définir la carte sur null. Vous devez démarrer le serveur distant avec;

-Dcom.sun.management.jmxremote.port=1234 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 

Vous pouvez jeter un oeil à wlshell qui est un petit utilitaire qui vous permet d'accéder à MBeans sur un serveur distant en utilisant une interface de texte ou d'un script, il peut être utilisé avec WebLogic, mais cela fonctionne pour n'importe quel programme Java où vous avez activé la surveillance à distance.

+0

Comment connaissons-nous l'utilisateur et le mot de passe ou comment pouvons-nous le définir. En utilisant un fichier de propriétés? –

+0

'MemoryUsage memuse = MemoryUsage.from ((CompositeData) o);' –

1
// Retrieve memory managed bean from management factory. 
MemoryMXBean memBean = ManagementFactory.getMemoryMXBean() ; 
MemoryUsage heap = memBean.getHeapMemoryUsage(); 
MemoryUsage nonHeap = memBean.getNonHeapMemoryUsage(); 

// Retrieve the four values stored within MemoryUsage: 
// init: Amount of memory in bytes that the JVM initially requests from the OS. 
// used: Amount of memory used. 
// committed: Amount of memory that is committed for the JVM to use. 
// max: Maximum amount of memory that can be used for memory management. 
System.err.println(String.format("Heap: Init: %d, Used: %d, Committed: %d, Max.: %d", 
    heap.getInit(), heap.getUsed(), heap.getCommitted(), heap.getMax())); 
System.err.println(String.format("Non-Heap: Init: %d, Used: %d, Committed: %d, Max.: %d", 
    nonHeap.getInit(), nonHeap.getUsed(), nonHeap.getCommitted(), nonHeap.getMax())); 
+0

À moins que je suis très confus , c'est le code pour accéder à l'information sur le même VM. Ce que j'essaie de comprendre est comment écrire un petit script de ligne de commande qui va tirer des informations d'un serveur en cours d'exécution dans une VM différente. – ThoughtfulHacking

+0

@ThoughtfulHacking vous avez raison, ce code est pour le même vm, j'essayais de faire le même code sur autre vm, il y a une méthode dans ManagementFactory nommée 'newPlatformMXBeanProxy' je l'ai utilisé pour obtenir les threads d'un autre vm, mais je n'a pas pu faire la même chose pour obtenir la gestion de la mémoire. La bonne réponse de votre question est la solution, mais j'ai vraiment besoin de le faire comme cette réponse ... – Tarek

5

@ La réponse de Kire semble bonne, mais je pensais ajouter quelques détails sur mon SimpleJMX package. Il contient un support de serveur qui vous permet d'exporter facilement des beans et inclut également une interface client simple qui fonctionne contre toute JVM qui exporte des informations JMX.

Pour accéder à l'utilisation de la mémoire que vous feriez quelque chose comme:

JmxClient client = new JmxClient("some.host.name", somePortNumber); 
// get the memory composite information 
CompositeData composite = 
     (CompositeData)client.getAttribute(new ObjectName("java.lang:type=Memory"), 
             "HeapMemoryUsage"); 
System.out.println(composite.get("committed")); 
+0

@Gray est beau, le client SimpleJMX fonctionne-t-il avec un serveur JMX standard? – raffian

+1

Il fait @raffian. Il utilise simplement le protocole JMX, donc fonctionne avec n'importe quel client/serveur JMX. – Gray

1

Voici comment vous obtenez le MemoryMXBean à distance (pour compléter @ réponse de Adamski):

MemoryMXBean memoryMXBeanProxy = JMX.newMXBeanProxy(
      conn, new ObjectName("java.lang:type=Memory"), MemoryMXBean.class); 
+0

Cette solution est meilleure que celle de @Kire, car il n'est pas nécessaire d'utiliser des moulages. –

Questions connexes