Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

274
Vistas
¿Qué es la 'categoría de memoria de servicio' del seguimiento de memoria nativa?

Tengo una aplicación java (JDK13) ejecutándose en un contenedor docker. Recientemente, moví la aplicación a JDK17 (OpenJDK17) y encontré un aumento gradual del uso de memoria por parte del contenedor acoplable.

Durante la investigación, descubrí que la NMT de la 'categoría de memoria de servicio' crece constantemente (15 mb por hora). Revisé la página https://docs.oracle.com/en/java/javase/17/troubleshoot/diagnostic-tools.html#GUID-5EF7BB07-C903-4EBD-A9C2-EC0E44048D37 pero esta categoría no se menciona allí.

¿Alguien podría explicar qué significa esta categoría de capacidad de servicio y qué puede causar un aumento tan gradual? También hay algunas categorías de memoria nuevas adicionales en comparación con JDK13. Tal vez alguien sepa dónde puedo leer detalles sobre ellos.

Aquí está el resultado del resumen del comando jcmd 1 VM.native_memory summary

 Native Memory Tracking: (Omitting categories weighting less than 1KB) Total: reserved=4431401KB, committed=1191617KB - Java Heap (reserved=2097152KB, committed=479232KB) (mmap: reserved=2097152KB, committed=479232KB) - Class (reserved=1052227KB, committed=22403KB) (classes #29547) ( instance classes #27790, array classes #1757) (malloc=3651KB #79345) (mmap: reserved=1048576KB, committed=18752KB) ( Metadata: ) ( reserved=139264KB, committed=130816KB) ( used=130309KB) ( waste=507KB =0.39%) ( Class space:) ( reserved=1048576KB, committed=18752KB) ( used=18149KB) ( waste=603KB =3.21%) - Thread (reserved=387638KB, committed=40694KB) (thread #378) (stack: reserved=386548KB, committed=39604KB) (malloc=650KB #2271) (arena=440KB #752) - Code (reserved=253202KB, committed=76734KB) (malloc=5518KB #23715) (mmap: reserved=247684KB, committed=71216KB) - GC (reserved=152419KB, committed=92391KB) (malloc=40783KB #34817) (mmap: reserved=111636KB, committed=51608KB) - Compiler (reserved=1506KB, committed=1506KB) (malloc=1342KB #2557) (arena=165KB #5) - Internal (reserved=5579KB, committed=5579KB) (malloc=5543KB #33822) (mmap: reserved=36KB, committed=36KB) - Other (reserved=231161KB, committed=231161KB) (malloc=231161KB #347) - Symbol (reserved=30558KB, committed=30558KB) (malloc=28887KB #769230) (arena=1670KB #1) - Native Memory Tracking (reserved=16412KB, committed=16412KB) (malloc=575KB #8281) (tracking overhead=15837KB) - Shared class space (reserved=12288KB, committed=12136KB) (mmap: reserved=12288KB, committed=12136KB) - Arena Chunk (reserved=18743KB, committed=18743KB) (malloc=18743KB) - Tracing (reserved=32KB, committed=32KB) (arena=32KB #1) - Logging (reserved=7KB, committed=7KB) (malloc=7KB #289) - Arguments (reserved=1KB, committed=1KB) (malloc=1KB #53) - Module (reserved=1045KB, committed=1045KB) (malloc=1045KB #5026) - Safepoint (reserved=8KB, committed=8KB) (mmap: reserved=8KB, committed=8KB) - Synchronization (reserved=204KB, committed=204KB) (malloc=204KB #2026) - Serviceability (reserved=31187KB, committed=31187KB) (malloc=31187KB #49714) - Metaspace (reserved=140032KB, committed=131584KB) (malloc=768KB #622) (mmap: reserved=139264KB, committed=130816KB) - String Deduplication (reserved=1KB, committed=1KB) (malloc=1KB #8)

La información detallada sobre el aumento de parte de la memoria es:

 [0x00007f6ccb970cbe] OopStorage::try_add_block()+0x2e [0x00007f6ccb97132d] OopStorage::allocate()+0x3d [0x00007f6ccbb34ee8] StackFrameInfo::StackFrameInfo(javaVFrame*, bool)+0x68 [0x00007f6ccbb35a64] ThreadStackTrace::dump_stack_at_safepoint(int)+0xe4 (malloc=6755KB type=Serviceability #10944)

Actualización n. ° 1 del 2022-01-17:

¡Gracias a @Aleksey Shipilev por su ayuda! Pudimos encontrar un lugar que causa el problema, está relacionado con muchas llamadas ThreadMXBean#.dumpAllThreads. Aquí está MCVE, Test.java:

Corre con:

 java -Xmx512M -XX:NativeMemoryTracking=detail Test.java

y verificar periódicamente la categoría de servicio como resultado de

 jcmd YOUR_PID VM.native_memory summary

Prueba Java:

 import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Test { private static final int RUNNING = 40; private static final int WAITING = 460; private final Object monitor = new Object(); private final ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean(); private final ExecutorService executorService = Executors.newFixedThreadPool(RUNNING + WAITING); void startRunningThread() { executorService.submit(() -> { while (true) { } }); } void startWaitingThread() { executorService.submit(() -> { try { monitor.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }); } void startThreads() { for (int i = 0; i < RUNNING; i++) { startRunningThread(); } for (int i = 0; i < WAITING; i++) { startWaitingThread(); } } void shutdown() { executorService.shutdown(); try { executorService.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { Test test = new Test(); Runtime.getRuntime().addShutdownHook(new Thread(test::shutdown)); test.startThreads(); for (int i = 0; i < 12000; i++) { ThreadInfo[] threadInfos = test.threadMxBean.dumpAllThreads(false, false); System.out.println("ThreadInfos: " + threadInfos.length); Thread.sleep(100); } test.shutdown(); } }
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Desafortunadamente (?), la forma más fácil de saber con certeza a qué se asignan esas categorías es mirar el código fuente de OpenJDK. La etiqueta NMT que está buscando es mtServiceability . Esto mostraría que la "capacidad de servicio" son básicamente interfaces de diagnóstico en JDK/JVM: JVMTI, volcados de almacenamiento dinámico, etc.

Pero el mismo tipo de cosas queda clara al observar que la muestra de seguimiento de pila que está mostrando menciona ThreadStackTrace::dump_stack_at_safepoint , eso es algo que vuelca la información del hilo, por ejemplo para jstack , volcado de montón, etc. Si tiene sospechas sobre el pérdida de memoria en ese código, puede intentar crear un MCVE que lo demuestre y enviar el error contra OpenJDK, o mostrárselo a un compañero desarrollador de OpenJDK. Probablemente sepa mejor qué está haciendo su aplicación para causar volcados de subprocesos, concéntrese allí.

Dicho esto, no veo ninguna fuga de memoria obvia en StackFrameInfo , ni puedo reproducir ninguna fuga con las pruebas de estrés, por lo que tal vez lo que está viendo es "solo" el vertido de subprocesos sobre las pilas de subprocesos cada vez más grandes. O lo captura cuando está ocurriendo el volcado de subprocesos. O... Es difícil decirlo sin el MCVE.

Actualización : después de jugar con MCVE, me di cuenta de que se reproduce con 17.0.1, pero no con el desarrollo principal JDK, JDK 18 EA o JDK 17.0.2 EA. Probé con 17.0.2 EA antes, así que no lo estaba viendo, maldita sea. La bisección entre 17.0.1 y 17.0.2 EA muestra que se arregló con el backport JDK-8273902 . 17.0.2 se lanza esta semana, por lo que el error debería desaparecer después de actualizar.

over 4 years ago · Santiago Trujillo Denunciar

0

Una posible razón para algunas fluctuaciones de la memoria sería algún otro proceso que use la conexión dinámica para adjuntar en JVM y depurar la aplicación y transferir información sabia de la aplicación al depurador. La capacidad de servicio está estrechamente relacionada con jdb (depurador de Java).

https://openjdk.java.net/groups/serviceability/ ingrese la descripción de la imagen aquí

El JDK abierto tiene esto también documentado analíticamente.

Facilidad de servicio en HotSpot

La Máquina Virtual HotSpot contiene varias tecnologías que permiten que su funcionamiento sea observado por otro proceso Java:

El Agente de Servicio (SA). Serviceability Agent es un componente privado de Sun en el depósito de HotSpot que fue desarrollado por los ingenieros de HotSpot para ayudar a depurar HotSpot. Luego se dieron cuenta de que SA podría usarse para crear >herramientas de mantenimiento para usuarios finales, ya que puede exponer objetos Java, así como >estructuras de datos HotSpot, tanto en procesos en ejecución como en archivos centrales.

Contadores de rendimiento de jvmstat. HotSpot mantiene varios contadores de rendimiento que están expuestos a procesos externos a través de un mecanismo de memoria privada compartida de Sun. >Estos contadores a veces se llaman perfdata.

La interfaz de herramienta de máquina virtual de Java (JVM TI) . Esta es una interfaz C estándar que es la implementación de referencia de JSR 163 - Plataforma JavaTM >Arquitectura de perfiles JVM TI es implementada por HotSpot y permite que un 'agente' de código nativo inspeccione y modifique el estado de la JVM.

La interfaz de Supervisión y Gestión. Esta es una API privada de Sun que permite monitorear y administrar aspectos de HotSpot.

Adjunto dinámico. Este es un mecanismo privado de Sun que permite que un proceso externo > inicie un subproceso en HotSpot que luego se puede usar para iniciar un agente para que se ejecute en ese HotSpot y para enviar información sobre el estado de HotSpot al proceso externo.

Seguimiento. DTrace es la galardonada función de seguimiento dinámico integrada en Solaris >10 y versiones posteriores. Se agregaron sondas DTrace a HotSpot que permiten monitorear muchos aspectos de la operación cuando HotSpot se ejecuta en Solaris. Además, HotSpot contiene un archivo jhelper.d que permite que dtrace muestre marcos de Java en seguimientos de pila.

soporte pstack. pstack es una utilidad de Solaris que imprime seguimientos de pila de todos los subprocesos en un proceso. HotSpot incluye soporte que permite que pstack muestre marcos de pila de Java.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda