machine jdk descargar java jvm

jdk - java runtime environment



¿Cómo bloqueas una JVM? (24)

¿Más corto? Usa la clase Robot para disparar CTRL + BREAK. Vi esto cuando estaba tratando de cerrar mi programa sin cerrar la consola (no tenía la funcionalidad de ''salir'').

Estaba leyendo un libro sobre habilidades de programación en el que el autor pregunta al entrevistado: "¿Cómo se bloquea una JVM?" Pensé que podrías hacerlo escribiendo un bucle for infinito que eventualmente usaría toda la memoria.

¿Alguien tiene alguna idea?


Depende de lo que quieres decir con crash.

Puedes hacer una recursión infinita para que se quede sin espacio en la pila, pero se bloqueará "con gracia". Obtendrá una excepción, pero la propia JVM se encargará de todo.

También puede usar JNI para llamar al código nativo. Si no lo haces de manera correcta, puedes hacer que se estrelle. La depuración de esos bloqueos es "divertida" (confía en mí, tuve que escribir una gran DLL de C ++ que llamamos desde un applet Java firmado). :)


El hardware roto puede bloquear cualquier programa. Una vez tuve un bloqueo de la aplicación reproducible en una máquina específica mientras funcionaba bien en otras máquinas con la misma configuración. Resulta que la máquina tenía RAM defectuosa.


El libro Java Virtual Machine de Jon Meyer tiene un ejemplo de una serie de instrucciones de bytecode que hicieron que JVM se volcara. No puedo encontrar mi copia de este libro. Si alguien tiene uno, búsquelo y publique la respuesta.


Este código bloqueará la JVM de maneras desagradables

import sun.dc.pr.PathDasher; public class Crash { public static void main(String[] args) { PathDasher dasher = new PathDasher(null) ; } }


JNI es una gran fuente de fallas. También puede bloquearse utilizando la interfaz JVMTI, ya que también debe escribirse en C / C ++.


La última vez que probé esto lo haría:

public class Recur { public static void main(String[] argv) { try { recur(); } catch (Error e) { System.out.println(e.toString()); } System.out.println("Ended normally"); } static void recur() { Object[] o = null; try { while(true) { Object[] newO = new Object[1]; newO[0] = o; o = newO; } } finally { recur(); } } }

Primera parte del archivo de registro generado:

# # An unexpected error has been detected by Java Runtime Environment: # # EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x000000006dad5c3d, pid=6752, tid=1996 # # Java VM: Java HotSpot(TM) 64-Bit Server VM (11.2-b01 mixed mode windows-amd64) # Problematic frame: # V [jvm.dll+0x2e5c3d] # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # --------------- T H R E A D --------------- Current thread (0x00000000014c6000): VMThread [stack: 0x0000000049810000,0x0000000049910000] [id=1996] siginfo: ExceptionCode=0xc00000fd, ExceptionInformation=0x0000000000000001 0x0000000049813fe8 Registers: EAX=0x000000006dc83090, EBX=0x000000003680f400, ECX=0x0000000005d40ce8, EDX=0x000000003680f400 ESP=0x0000000049813ff0, EBP=0x00000000013f2df0, ESI=0x00000000013f0e40, EDI=0x000000003680f400 EIP=0x000000006dad5c3d, EFLAGS=0x0000000000010206


Lo estoy haciendo ahora, pero no del todo seguro de cómo ... :-) JVM (y mi aplicación) a veces simplemente desaparecen por completo. Sin errores lanzados, nada registrado. Deja de funcionar para no funcionar en absoluto al instante sin previo aviso.


No es un bloqueo, pero está más cerca de un bloqueo que la respuesta aceptada de usar System.exit

Puede detener la JVM llamando

Runtime.getRuntime().halt( status )

Según los documentos:

"Este método no provoca el inicio de los enganches de cierre y no ejecuta los finalizadores no invocados si se ha habilitado la finalización a la salida".


No llamaría un lanzamiento de OutOfMemoryError o Error. Estas son solo excepciones normales. Para bloquear realmente una VM hay 3 formas:

  1. Use JNI y crash en el código nativo.
  2. Si no está instalado un administrador de seguridad, puede usar el reflejo para bloquear la máquina virtual. Esto es específico de VM, pero normalmente una VM almacena un grupo de punteros a recursos nativos en campos privados (por ejemplo, un puntero al objeto de cadena nativo se almacena en un campo largo en java.lang.Thread ). Simplemente cámbialos a través de la reflexión y la máquina virtual se bloqueará tarde o temprano.
  3. Todas las máquinas virtuales tienen errores, por lo que solo tiene que activar uno.

Para el último método, tengo un pequeño ejemplo, que bloqueará un Sun Hotspot VM tranquilamente:

public class Crash { public static void main(String[] args) { Object[] o = null; while (true) { o = new Object[] {o}; } } }

Esto conduce a un desbordamiento de la pila en el GC, por lo que no obtendrá Error sino una falla real que incluye un archivo hs_err *.


Si cambia ese bucle infinito por una llamada recursiva a la misma función, entonces obtendría una excepción de desbordamiento de pila:

public static void main(String[] args) { cause(); } public void cause() { cause(); }


Si crea un proceso de subproceso que genere infinitamente más subprocesos (que generen más subprocesos, lo que ...) eventualmente causará un error de desbordamiento de pila en la propia JVM.

public class Crash { public static void main(String[] args) { Runnable[] arr = new Runnable[1]; arr[0] = () -> { while (true) { new Thread(arr[0]).start(); } }; arr[0].run(); } }

Esto me dio la salida (después de 5 minutos, mire su ram)

An unrecoverable has occurred. # # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x0000000070e53ed7, pid=12840, tid=0x0000000000101078 # # JRE version: Java(TM) SE Runtime Environment (8.0_144-b01) (build 1.8.0_144-b01) # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode windows-amd64 compressed oops) # Problematic frame: #


Si define un bloqueo como un aborto de proceso debido a una situación no controlada (es decir, sin Excepción o Error de Java), esto no se puede hacer desde Java (a menos que tenga permiso para usar la clase sun.misc.Unsafe). Este es todo el punto del código administrado.

Los típicos bloqueos en el código nativo se producen al desviar referencias a áreas de memoria incorrectas (dirección nula o mal alineadas). Otra fuente podría ser instrucciones de máquinas ilegales (códigos de operación) o señales no controladas de la biblioteca o llamadas al kernel. Ambos pueden activarse si la JVM o las bibliotecas del sistema tienen errores.

Por ejemplo, el código JITed (generado), los métodos nativos o las llamadas al sistema (controlador de gráficos) pueden tener problemas que conduzcan a bloqueos reales (era bastante común tener un bloqueo cuando usaba funciones ZIP y se quedaban sin memoria). En esos casos, el controlador de bloqueo de la JVM entra en acción y vuelca el estado. También podría generar un archivo de núcleo del sistema operativo (Dr. Watson en Windows y volcado del núcleo en * nix).

En Linux / Unix puede realizar fácilmente un bloqueo de JVM enviándole una Señal al proceso en ejecución. Nota: no debe usar SIGSEGV para esto, ya que Hotspot capta esta señal y la vuelve a lanzar como NullPointerException en la mayoría de los lugares. Entonces, es mejor enviar un SIGBUS por ejemplo.


Si quiere bloquear JVM, use lo siguiente en Sun JDK 1.6_23 o a continuación:

Double.parseDouble("2.2250738585072012e-308");

Esto se debe a un bug en Sun JDK, que también se encuentra en OpenJDK. Esto se soluciona desde Oracle JDK 1.6_24 en adelante.


Si quiere fingir que se ha quedado sin memoria, puede hacer

public static void main(String[] args) { throw new OutOfmemoryError(); }

Sé un par de formas de hacer que el JVM descargue un archivo de error llamando a métodos nativos (los que están incorporados), pero probablemente es mejor que usted no sepa cómo hacerlo. ;)


Si un ''Crash'' es algo que interrumpe el jvm / programa de la terminación normal, entonces una excepción sin manejo podría hacer esto.

public static void main(String args[]){ int i = 1/0; System.out.print(i); // This part will not be executed due to above unhandled exception }

Por lo tanto, depende de qué tipo de CRASH?!


Una implementación perfecta de JVM nunca se bloqueará.

Para bloquear una JVM, aparte de JNI, necesita encontrar un error en la VM. Un bucle infinito solo consume CPU. La asignación infinita de memoria solo debería causar OutOfMemoryError en una JVM bien construida. Esto probablemente causaría problemas para otros subprocesos, pero una buena JVM aún no debería fallar.

Si puede encontrar un error en el código fuente de la máquina virtual y, por ejemplo, causar un error de segmentación en el uso de la memoria de la implementación de la máquina virtual, entonces puede bloquearla.


Utilizar esta:

import sun.misc.Unsafe; public class Crash { private static final Unsafe unsafe = Unsafe.getUnsafe(); public static void crash() { unsafe.putAddress(0, 0); } public static void main(String[] args) { crash(); } }

Esta clase debe estar en el classpath de arranque porque está usando código de confianza, así que ejecute esto:

java -Xbootclasspath / p :. Choque


Vine aquí porque también me encontré con esta pregunta en The Apasionate Programmer , de Chad Fowler. Para aquellos que no tienen acceso a una copia, la pregunta se enmarca como una especie de filtro / prueba para los candidatos que se entrevistan para un puesto que requiere "muy buenos programadores de Java".

Específicamente, él pregunta:

¿Cómo escribirías un programa, en Java puro, que causaría la falla de la Máquina Virtual de Java?

He programado en Java por más de 15 años, y esta pregunta me pareció desconcertante e injusta. Como han señalado otros, Java, como lenguaje administrado, está específicamente diseñado para no bloquearse . Por supuesto, siempre hay errores de JVM, pero:

  1. Después de más de 15 años de JRE a nivel de producción, es raro.
  2. Es probable que cualquiera de estos errores sea parcheado en la próxima versión, entonces, ¿qué tan probable es que usted como programador se tope y recuerde los detalles del conjunto actual de JRE show-stoppers?

Como otros han mencionado, algunos códigos nativos a través de JNI son una forma segura de bloquear un JRE. Pero el autor mencionó específicamente en Java puro , así que está fuera.

Otra opción sería alimentar los códigos de bytes falsos de JRE; es bastante fácil descargar algunos datos binarios basura en un archivo .class, y pedirle al JRE que lo ejecute:

$ echo ''crap crap crap'' > crap.class $ java crap Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 1668440432 in class file crap

¿Eso cuenta? Quiero decir que el JRE en sí no se ha estrellado; detectó correctamente el código falso, lo informó y salió.

Esto nos deja con los tipos más obvios de soluciones, como explotar la pila por recursión, quedarse sin memoria del montón a través de asignaciones de objetos o simplemente lanzar RuntimeException . Pero esto solo hace que el JRE salga con un Error o una excepción similar, lo que, nuevamente, no es realmente un bloqueo .

Entonces, ¿qué queda? Realmente me encantaría escuchar lo que el autor realmente tenía en mente como una solución adecuada.

Actualización : Chad Fowler respondió aquí .

PD: es un gran libro por lo demás. Lo recogí para obtener apoyo moral mientras aprendía Ruby.



en winxpsp2 w / wmp10 jre6.0_7

Desktop.open (uriToAviOrMpgFile)

Esto provoca que un subproceso generado arroje un punto de acceso Throwable y bloqueado no capturado

YMMV


la forma más corta posible :)

public class Crash { public static void main(String[] args) { main(args); } }


JNI . De hecho, con JNI, el bloqueo es el modo de operación predeterminado. Tienes que trabajar muy duro para que no se cuelgue.


Lo más parecido a una única "respuesta" es System.exit() que finaliza la JVM inmediatamente sin una limpieza adecuada. Pero aparte de eso, el código nativo y el agotamiento de recursos son las respuestas más probables. Alternativamente, puede buscar errores en el rastreador de errores de Sun en su versión de la JVM, algunos de los cuales permiten escenarios de bloqueo repetibles. Solíamos tener bloqueos semi regulares cuando nos acercamos al límite de memoria de 4 Gb en las versiones de 32 bits (generalmente usamos 64 bits ahora).