agent Java în serviciul de JVM


Probabil mulți au auzit sau experimentat o astfel de parametru ca -javaagent JVM, vedeți această opțiune, puteți utiliza Jrebel Plumbr sau ar putea arăta astfel JAVA_OPTS = -javaagent: [cale / către /] jrebel.jar sau cam asa -javaagent: / calea-to /plumbr.jar
Deși javaagent a apărut în versiunea de Java 1.5, mulți dezvoltatori nu au folosit niciodată posibilitatea agenților și au o idee vagă ce este.
Ce fel de agent? De ce el poate vom avea nevoie și cum să scrie dumneavoastră?

Așa cum am scris mai sus javaagent este unul dintre parametrii JVM, care vă permite să specificați un agent care vor fi difuzate cererea dumneavoastră, ci mai degrabă va fi rulat înainte de a rula aplicația. agentul însuși este o aplicație independentă, care oferă acces la mecanismul de manipulare a bytecode (java.lang.instrument) în timpul rulării. Aceasta este într-o coajă de nucă. Documentația oficială poate fi citit aici. dar este destul de slaba. Ceva neclar? Deci, să se ocupe. Cel mai bine este să înțelegem exemple.

Scriem agentul elementar

Vă rugăm să rețineți, agentul trebuie să pună în aplicare o metodă cu următoarea semnătură premain
public static void premain (String args);
sau
premain public static void (String args, instrumentație Inst);

agent de clasă ar trebui să fie ambalate într-un borcan și conține MANIFEST.MF. atribut obligatoriu
PreMain-Class - indică un agent de clasă cu metoda premain. Există și alte atribute ale agentului, dar ele sunt opționale, iar acum nu mai avem nevoie.

Asta e modul în care ne vom uita MANIFEST.MF.
nu uitați să adăugați o linie nouă la sfârșitul fișierului

Acum am totul pachet într-un borcan

În cele din urmă testul de clasă

AgentTester rula din linia de comandă

Acest exemplu arată că:
  • Metoda premain executate înainte de a apela aplicația principală de bază.
  • agent este indicat de parametrul -javaagent: jarpath [= opțiuni]

Să încercăm să învețe de la agentul de orice utilizare


În general, mecanismul de agenți pentru manipulare bytecode. Dar eu va modifica codul de octet direct în acest articol nu vom altfel posibil pentru a merge mult mai departe, cu mult dincolo de post. Cine sunt interesați se pot uita la javassist ca instrumentele standard pentru lucrul cu bytecode nu este.

Să scrie AgentCounter care va afișa numele clasei încărcate și a contoriza numărul de clase încărcate. Deci, vom putea observa classloader`a de lucru.


Vă rugăm să rețineți, eu folosesc acum un alt premain metodă de semnătură. Obiectul instrumentație I trec ClassTransformer care face toate lucrările. ClassTransformer va fi declanșat de fiecare dată când este încărcat clasa. Dacă doriți să utilizați ClassTransformer, trebuie să pună în aplicare interfață java.lang.instrument.ClassFileTransformer și adăugați obiectul prin metoda Instrumentation.addTransformer


classfileBuffer - acesta este octet-codul clasei curente reprezentat ca o matrice octet, pentru redefinire lui de transformator ar trebui să se întoarcă o nouă gamă de octeți, în acest exemplu, nu se schimba conținutul clasei astfel încât returna doar aceeași matrice.

Agent Pack și transformator într-un borcan nou

Bit modifica Tester clasa

Start nou agent AgentTester c
pentru diferite versiuni ale rezultatelor java pot diferi

Dacă executați orice aplicație întreprindere cu un agent, puteți obține unele rezultate interesante, cum ar fi unul dintre proiectele după începerea mi-a dat următoarele:

Se măsoară dimensiunea obiectelor Java


Luați în considerare un alt exemplu de utilizare a agenților. Scrieți o clasă care va reveni dimensiunea obiectelor Java și javaagent va juca un rol-cheie. Cine altcineva, dar JVM poate cunoaște dimensiunea reală a obiectului creat. Instrumentation în metoda de interfață este remarcabil getObjectSize lung (Object objectToSize), care returnează dimensiunea obiectului. Dar, din cererea noastră de a avea acces la agentul? Și pentru a face ceva special și nu trebuie să, javaagent adăugat automat la classpath și putem adăuga numai la tipul de agent de instrumentație câmp instrumentație și inițializa-l în metoda premain.


Vom avea acces la AgentMemoryCounter.getSize metoda (obj) din clasa de aplicare.

Rezultatele aplicației pot fi după cum urmează

Vă rugăm să rețineți că getObjectSize () metoda nu ia în considerare dimensiunea obiectelor încorporate adică numărate doar de memorie cheltuit pe un obiect de referință.

concluzie

> AgentCounter care va afișa numele clasei încărcate și a contoriza numărul de clase încărcate
Există o modalitate de a contoriza numărul de instanțe ale acestei clase

Întotdeauna foarte interesat de modul de a afla: „Cine a creat cat mai multe linii sau int [], și pentru a găsi părinții acestor blocuri?“
Poate că este deja decis cu ajutorul agentului existent sau un debugger?

Pentru a face acest lucru, există profilers. De exemplu, YourKit Java Profiler. Din liber, cum ar fi Eclipse Memory Analyzer Tool.

Timpul indicat în fusul orar, care este montat pe aparat.

articole similare