Még mitől durranhat el a JVM agya

Akarom mondani, milyen nemes célra folyathatja a megabyte-ok százait/ezreit, illetve hogyan lehet szabályozni/korlátozni.
Előzmény: Blog - A memóriámmal van a baj...

Forrás:
https://stackoverflow.com/questions/53451103/java-using-much-more-memor…

Heap: itten vannak a nemlokális objektumok (megjegyzés: nincsenek lokális objektumok, ami lokális, az vagy elemi típus, vagy pointer egy objektumra) -Xms -Xmx opciókkal szabályozható (initial, maximal)

Metaspace: Az osztályok metaadatai vannak benne, ez is nagyon jó valamire, a méretét az -XX:MaxMetaspaceSize=-vel lehet korlátozni.

Code cache: A JIT kapcsán tölt be valamilyen fontos és hasznos szerepet, -XX:ReservedCodeCacheSize  opció.

Direct buffer: Amit a ByteBuffer.allocateDirect-tel tudunk foglalni. -XX:MaxDirectMemorySize= opció

Stack: A stack (szálankénti) mérete a -Xss opcióval szabályozható.

Natív malloc: Ezt nem szabályozza és korlátozza semmi, viszont ha beleszalad valamilyen korlátba (pl. RLIMIT_AS), akkor nem lesz szemétgyűjtés, hanem hiba van és kész. A jó hír az, hogy ha nincs JNI, akkor nincs natív malloc. A rossz hír az, hogy a Java runtime tele van JNI-vel, például egy fájlmegnyitás előtt az első teendő a `JNU_GetStringPlatformChars` hívása, ami malloc-ot hív.

Hozzászólások

Szerkesztve: 2020. 05. 21., cs - 12:46

jmx-en keresztul lehet monitorzni az app memoriafoglalasat. az adatokat zabbixban jelenitheted meg. regebben kezzel kellett, mara benne a van. java gateway a neve.

https://www.zabbix.com/documentation/4.2/manual/config/items/itemtypes/…

ezeket a meropontokat minden egyeb kodmodositas nelkul el tudod erni, mert a jvm adja:

https://docs.oracle.com/javase/1.5.0/docs/guide/management/jconsole.html

jconsolt is nezegetheted, de hoszzabb tavon erdemesebb egy zabbix.

a zabbix_server.confban a startpollernel ne felejtsd bekapcsolni, mert alapbol nem indul el.

Köszönöm, ez jónak tűnik!
Quickstartként ez már elég:

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

Ezt még SSL-re fogom átállítani, hogy ne panaszoljon a jconsole

Szerk: ez lett:

java -cp .
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=20001 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=true \
-Dcom.sun.management.jmxremote.registry.ssl=true \
-Djavax.net.ssl.keyStore=application_default.p12 \
-Djavax.net.ssl.keyStoreType=pkcs12 \
-Djavax.net.ssl.keyStorePassword=changeit \
 TestMe

Persze a jconsole így nem áll vele szóba Connection failed: non-JRMPserver at remote endpoint, de hát mi tökéletes ebben a földi siralomvölgyben?

Szerk: begyömködtem a házibarkács root-cert-et a `cacerts`-be, ettől megjött a jókedve.

Most újra próbálva (másik gépről), ezeket kellett neki szórni (a portot ad-hoc tologatom, ahol éppen egy lyukat látok a hálózatos kollégák éberségén):
 

java -cp . \
    -Dcom.sun.management.jmxremote \
    -Dcom.sun.management.jmxremote.port=8081 \
    -Dcom.sun.management.jmxremote.rmi.port=8081 \
    -Dcom.sun.management.jmxremote.local.only=false \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=false \
    Executable

Illetve SSL-lel:

java -cp . \
    -Dcom.sun.management.jmxremote \
    -Dcom.sun.management.jmxremote.port=8081 \
    -Dcom.sun.management.jmxremote.rmi.port=8081 \
    -Dcom.sun.management.jmxremote.local.only=false \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=true \
    -Dcom.sun.management.jmxremote.registry.ssl=true \
    -Djavax.net.ssl.keyStore=application_default.p12 \
    -Djavax.net.ssl.keyStoreType=pkcs12 \
    -Djavax.net.ssl.keyStorePassword=changeit \
    Executable

Most ott tartok, hogy 'sima Java programhoz' eljutok így, de a Docker-es springboot-os csodaprogramhoz nem (tudom ám halmozni az akadályozó tényezőket, mi?). A fő gyanusítottam a tomcat; egyelőre annyit tudok, hogy a kapcsolat átjut a Dockeren át:

$ sminitel -ssl tavoli_IP 8081
20200522.100536.348 Connected to tavoli_IP:8081 from helyi_IP:55898 via SSL
proto=TLSv1.3 enc=AESGCM(256) mac=AEAD kx=any au=any

Egy kolléga: stackoverflow - Unable to connect JConsole to my Springboot application
https://docs.spring.io/spring-boot/docs/1.2.0.M2/reference/html/product…

Szerk: Egy másik tesztben egy standalone (nem springboot-embedded) tomcathez kapcsolódta jconsole-lal (távoli gép, SSL, nincs auth), az sikerült.

Szerk: Még azt is látni vélem, hogy a derék jconsole nem egy, hanem 3-5 TCP kapcsolatot nyit a távoli partnerhez.

Szerk: Kezdem sejteni, hogy erre való a java.rmi.server.hostname paraméter. Ez akkor lenne igazán jó, ha a dockerbe is beinjeketálnám a fizikai gép IP-címét. Illetve, ha már úgyis gépenként kell *.p12 fájlt generálni:
 

openssl pkcs12 -in jmx.keystore.p12 -clcerts -nokeys -passin pass:changeit |
awk '/friendlyName: / { print $2; exit; }'