2009-05-13 22 views
7

¿Cómo puedo determinar la dirección en memoria del montón de Java para una JVM que se ejecuta en el proceso actual? Es decir, ¿obtiene un puntero void * o equivalente al área contigua de memoria que la JVM ha asignado para el montón, utilizando Java, C u otras llamadas?¿Cómo obtener la dirección de memoria del montón de Java?

Matlab tiene una JVM incrustada en su proceso. La memoria que asigna la JVM no está disponible para las matrices de Matlab, y de esto, la pila es importante, ya que requiere una gran porción contigua de memoria y nunca se contrae, y Matlab también necesita memoria contigua para sus matrices. Si el montón se reasigna durante la expansión, eso podría provocar la fragmentación.

Me gustaría instrumentar mi proceso para examinar la interacción entre el montón de Java y la vista de memoria de Matlab, y para saber cuándo se mueve debido al cambio de tamaño, preferiblemente todo desde dentro del proceso. Esto necesita la dirección del montón. Es fácil encontrar el tamaño de almacenamiento dinámico de java.lang.Runtime, pero no su dirección en la memoria. ¿Cómo puede hacerse esto?

Estoy ejecutando Sun's JRE 1.6.0_04 en un proceso de Matlab R2008b en Windows XP y Server 2003. Me doy cuenta de que probablemente deba ser una técnica específica del proveedor. El proceso ejecuta el código que hemos escrito, por lo que podemos usar códigos personalizados de Java, Matlab, JNI y C/C++. Las llamadas a métodos Java o los ganchos admitidos en la JVM serían preferibles a la piratería de bajo nivel.

EDITAR: El objetivo de esto es examinar la interacción entre el GC de la JVM y el GC de Matlab. No necesito ver el montón de Java y no leeré nada de ese recuerdo; Solo quiero ver dónde está en el contexto del espacio general de la memoria virtual en el que el GC de Matlab también está tratando de encajar los datos.

+0

¿El objetivo final es el análisis de la interacción de memoria java/matlab? o para acceder a la misma memoria para el almacenamiento de datos? – basszero

+0

@basszero: solo análisis de la interacción de memoria java/matlab. no hay lectura o escritura dentro de ese recuerdo. –

Respuesta

2

A n forma rápida' sucio para obtener la dirección del montón real de la JVM es para saltar en WinDbg, adjuntando a la JVM y emitir un solo comando! Dirección. En algún lugar alrededor de 0x2 ???????(Diferencia entre las versiones de jvm pero permanece estático para esa versión) será un VAD grande marcado PAGE_EXECUTE_READWRITE, este es el montón de su JVM en la memoria del proceso.

Para confirmar, puede establecer un punto de interrupción en kernel32! VirtualAlloc y luego de la inicialización de JVM en el módulo JVM.DLL, usted golpeará en la llamada a VirtualAlloc mostrándole la asignación de jvm en su pila. Si revisa el código de esta llamada, puede ver cómo se calcula la dirección.

+0

Lo siento, me tomó tanto tiempo para aceptar; se pelaron en otro trabajo por un tiempo. No sabía sobre WinDbg. Muy útil. –

1

Si lo que desea es obtener la pila de JVM para reducir el tamaño podría intentar jugar con los parámetros tales como la cromatografía gaseosa -XX: MaxHeapFreeRatio (ver http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp)

no creo que se puede obtener un puntero a la de Java montón con JNI. Sin embargo, el montón de Java es solo memoria asignada al proceso por Windows desde uno de los montones de procesos.

Puede obtener los montones de proceso de su código C++ utilizando la función GetProcessHeaps (http://msdn.microsoft.com/en-us/library/aa366571(VS.85).aspx) y luego comenzar a recorrerlos con la función HeapWalk. Hay un buen ejemplo en http://www.abstraction.net/content/articles/analyzing%20the%20heaps%20of%20a%20win32%20process.htm. Es posible que pueda detectar qué bloques asignados son utilizados por el montón de Java buscando ciertos patrones de bytes (el código fuente de JVM puede darle algunas pistas sobre qué buscar, pero ¡buena suerte descubriéndolo!)

+0

Esto suena prometedor; No sabía acerca de GetProcessHeaps. Vamos a intentar juntar esto para nuestra aplicación. –

+1

"el montón de Java es solo memoria asignada al proceso por Windows desde uno de los montones de proceso". Esto no es cierto, el montón de Java está asignado (en Windows) a través de kernel32! VirtualAlloc y como tal no es de uno de los montones de procesos. – QAZ

2

Retrocediendo un poco ... ¿Podría ir con un montón de Java de tamaño fijo? En ese momento, las preocupaciones sobre la reasignación y la fragmentación desaparecen.

En una invocación de Java autónoma, implica especificar algo como -Xmx500m y -Xms500m para un montón de 500Mb. Tendría que traducir eso en lo que Matlab quiere.

+0

Esto podría ayudar, pero la compensación es que la memoria asignada al montón de Java no se puede usar para las matrices de Matlab. En algunas ejecuciones, los usuarios hacen cosas de la GUI que hacen un uso intensivo de la pila de Java, en otras, cosas numéricas intensas de código M. Un montón de tamaño fijo arreglaría la fragmentación a costa de la flexibilidad. Esa es en realidad la razón por la que quiero esta instrumentación: para ver si valdría la pena el intercambio de montón fijo al preguntar "¿cuánta fragmentación está ocurriendo debido al montón de realloc?" –

0

El GC puede mover datos en cualquier momento para compactar la memoria. Entonces no hay un punto fijo para los objetos en el Heap de Java. Puede usar un ByteBuffer.allocateDirect() que asigna memoria en el espacio "C" en lugar del montón y se fija en la memoria.

+0

No estoy buscando la ubicación de objetos individuales dentro del montón de Java, sino la ubicación de todo el almacenamiento dinámico de Java dentro del espacio de direcciones virtuales del proceso. –

0

No creo que haya una manera de hacer lo que quiera, sin usar una JVM personalizada. En teoría, podría usar OpenJDK y parchearlo o habilitar algún rastreo (no estoy seguro si hay uno que se adapte a sus necesidades). Creo N herramienta de monitoreo externo, como the process explorer podría resolver su problema

Cuestiones relacionadas