2010-06-05 12 views
15

He leído en muchos hilos que es imposible desactivar la recolección de basura en la JVM de Sun. Sin embargo, para el propósito de nuestro proyecto de investigación necesitamos esta característica. ¿Alguien puede recomendar una implementación de JVM que no tenga recolección de basura o que permita apagarla? Gracias.JVM sin recolección de basura

+4

Java sin recolección de basura, es como, bueno C/C++ !!! –

+1

Según http://forums.java.net/jive/thread.jspa?messageID=208939&tstart=0, el gc podría estar deshabilitado en las versiones anteriores de Java, pero ya no es posible. –

+8

@Mitch Wheat, no. está ** lejos ** de C++, no hay desbordamientos de búfer y poco o ningún comportamiento indefinido. –

Respuesta

15

Quería encontrar una manera rápida de mantener todos los objetos en la memoria para una simple prueba inicial de concepto.

La forma más simple de hacer esto es ejecutar la JVM con un montón que es tan grande que el GC nunca necesita ejecutarse. Establezca las opciones -Xmxy-Xms en un valor grande y active el registro de GC para confirmar que el GC no se ejecute durante la prueba.

Esto será más rápido y más sencillo que modificar la JVM.


(En retrospectiva, esto puede no funcionar. Vagamente recuerdo haber visto evidencia de que implicaba que la JVM no siempre caso al valor -Xms, especialmente si era muy grande. Sin embargo, este enfoque es la pena tratando antes de intentar un enfoque mucho más difícil ... como modificar la JVM.)

Además, todo esto me parece innecesario (incluso contraproducente) por lo que en realidad estás tratando de lograr. El GC no arrojará objetos a menos que sean basura. Y si son basura, no podrás usarlos. Y el rendimiento de un sistema con GC deshabilitado/negado no es indicativo de cómo funcionará una aplicación real.

4

Sun's JVM no tiene esa opción. AFAIK, ninguna otra JVM tiene esta opción tampoco.

No indicó qué es exactamente lo que está tratando de lograr, pero tiene una de dos opciones: utilizar un generador de perfiles y ver exactamente lo que hace el GC, de ese modo puede tener en cuenta sus efectos. La otra es compilar una de las JVM de la fuente y deshabilitar GC desde allí.

+1

Gracias por la respuesta. Básicamente estoy perfilando programas Java. Quería encontrar una manera rápida de mantener todos los objetos en la memoria para una simple prueba inicial de concepto. –

8

Dependiendo de sus necesidades esto quizás podría trabajar:

Mediante la opción -Xbootclasspath puede especificar su propia implementación de clases de la API. Podría, por ejemplo, anular la implementación de Object y agregar al constructor un globalList.add(this) para evitar que los objetos sean recolectados. Es un hack seguro, pero para un simple estudio de caso es quizás suficiente.

Otra opción es tomar un jvm de código abierto y comentar las partes que inician la recolección de elementos no utilizados. Supongo que no es tan complicado.

+1

Overriding Object sonaba como una idea brillante. Pero cuando lo probé, me dio un error con un gran rastro de pila. Creo que tiene sentido, ya que cualquier código que quiera ejecutar en el constructor de Object necesitará invocar el constructor del Object. –

+2

Buen punto. Un simple globalList.add (esto) probablemente causará una recursión infinita. Tendría que hacer algo más cortante. Por ejemplo, podría implementar su propia estructura de listas, que se excluye de la inserción en la lista. – aioobe

+0

¿Esto evitará el ciclo de "colección pequeña" para la colección generacional? – cody

1

Tal vez podría tratar de hacer que la memoria disponible de su VM sea suficiente para que el GC no se ejecute nunca.

Mi (todo limitado) experiencia me lleva a sugerir que la máquina virtual es, por defecto, extremadamente vago y muy reacio a ejecutar GC.

dando -Xmx 16384M (o algo así) y asegurarse de que su sujeto de investigación se mantiene muy por debajo de ese límite, puede darle el entorno que desea obtener, aunque incluso entonces obviamente no estará garantizado.

1

¿Se puede obtener una JVM de fuente abierta y desactivar su GC, por ejemplo Sun's Hotspot?

Si no hubiera recolección de basura, ¿cuál sería la semántica del código como esta?

public myClass { 

     public void aMethod() { 

      String text = new String("xyz"); 

     } 

} 

En ausencia de GC, ningún elemento nuevo y con una referencia de ámbito de pila nunca podría ser recuperado. Incluso si sus propias clases pudieran decidir no usar variables locales como esta, o usar solo tipos primitivos, no veo cómo usarían de forma segura cualquier biblioteca Java estándar.

Me interesaría saber más sobre su escenario de uso.

+1

"recién salido de la pila"? – aioobe

+0

Si va a hackear una JVM de código abierto, ¿por qué no comenzar con el Hotspot de Sun? – Ken

+0

@aioobe Sí, podría haberlo redactado mejor; siéntase libre de editarlo si lo desea. El ejemplo de código que espero muestra a qué me refiero. Al salir del método, la variable local * text * se ha ido, no tenemos ninguna referencia al objeto nuevo y no hay forma de organizarlo. – djna

0

Si tuviera este problema que obtendría de IBM Jikes Research Virtual Machine porque:

  • El sistema de tiempo de ejecución está escrito en Java en sí (con extensiones especiales)
  • Todo el asunto fue diseñado como un vehículo de investigación y es relativamente fácil de modificar.

No se puede desactivar GC para siempre, ya que los programas Java hacen asignar y finalmente se quedará sin memoria, pero es muy posible que usted puede retrasar GC durante la duración del experimento contando la JVM no comenzará a recopilar hasta que el montón se vuelva realmente grande. (Ese truco también podría funcionar en otras JVM, pero no sabría dónde encontrar las perillas para comenzar a girar.)

1

Eche un vistazo a Oracle's JRockit JVM. He visto muy buen rendimiento casi determinista en el hardware de Intel con esta JVM y puede pinchar el tiempo de ejecución con la utilidad Mission Control para ver qué tan bien funciona.

Aunque no puede apagar el GC por completo, creo que puede usar la opción -Xnoclassgc para deshabilitar la colección de clases. El GC se puede sintonizar a minimize latency a expensas de dejar crecer el consumo de memoria. Es posible que necesite una licencia para reducir la latencia tan bajo como lo necesite si va por esta ruta.

También hay una versión en tiempo real de JRockit JVM disponible, pero no creo que haya una versión gratuita de este disponible.

1

Solo puede apagar el GC si no es realmente necesario (de lo contrario su aplicación se quedaría sin memoria) y si no necesitara GC, no debería funcionar de todos modos.

La opción más simple sería no descartar ningún objeto, esto evitará que se realice el GC (y configure la memoria máxima muy alta para que no se acabe).

Es posible que obtenga GC en el arranque y que considere que no utilizar el GC cuando funciona aceptablemente.

1

Existe realmente un truco sucio para detener momentáneamente el GC. Primero crea una matriz ficticia en Java. Luego, en JNI, use la función GetPrimitiveArrayCritical para obtener el puntero a la matriz. Sun JVM deshabilitará GC para garantizar que la matriz nunca se mueva y el puntero siga siendo válido. Para volver a habilitar GC, puede llamar a la función ReleasePrimitiveArrayCritical en el puntero. Pero esto es muy específico de la implementación, ya que otras VM impl pueden fijar el objeto en lugar de deshabilitar el GC por completo.(Probado para trabajar en Oracle Jdk 7 & 8)

+0

¿Podría proporcionar el código fuente [Configuración de prueba] para el enfoque que dijo .. – Pushparaj

-1

la cuestión es viejo, pero para aquellos que puedan estar interesados, no es una propuesta para

Desarrollar un GC que sólo se encarga de la asignación de memoria, pero no se implementar cualquier mecanismo de recuperación de memoria real. Una vez que el almacenamiento dinámico de Java disponible se agota, realice el cierre ordenado de JVM.

JEP draft: Epsilon GC: The Arbitrarily Low Overhead Garbage (Non-)Collector

Cuestiones relacionadas