Experiencia de entrevista
Recuerdo que hace unos años, Ali fue a una entrevista y le hizo esta pregunta:
¿Se asignan objetos en Java en el montón? ¡Explicar por qué!
En ese momento, me preguntaron con una mirada atónita, y al instante me rompieron a la perfección. En ese momento, no sabía qué puntos de conocimiento estaba probando. ¿No está el objeto asignado en el montón? Al final, no hubo más, volví y esperé el aviso.
Asignación de objetos
Casi todos los objetos se asignan en el montón. Esta es una oración que todos ven a menudo, pero esta oración no significa todos. Los objetos en la JVM se pueden asignar en la pila, pero la premisa es juzgar el estado de escape.
Estado de escape del objeto
1. GlobalEscape
Es decir, el alcance de un objeto escapa al método actual o al hilo actual. Hay varios escenarios:
- El objeto es una variable estática
- El objeto es un objeto que se ha escapado
- Objeto como valor de retorno del método actual
2. Escape de parámetro (ArgEscape)
Es decir, se pasa un objeto como parámetro de método o se hace referencia a él mediante un parámetro, pero no se produce ningún escape global durante la llamada. Este estado está determinado por el bytecode del método llamado.
3. Sin escape
Es decir, el objeto del método no escapa.
Código de análisis de escape
public class EscapeAnalysisTest {
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
for (int i = 0; i < 50000000; i++) {
allocate(); } System.out.println((System.currentTimeMillis() - start) + " ms");
Thread.sleep(600000); }
static void allocate() {
MyObject myObject = new MyObject(2020, 2020.6); }
static class MyObject { int a; double b; MyObject(int a, double b)
{ this.a = a; this.b = b;
} }}
En el proceso de llamar a este código, el objeto myboject pertenece al escape global y la JVM puede asignarlo en la pila.
Luego, observe la diferencia activando y desactivando el interruptor DoEscapeAnalysis.
Habilitar el análisis de escape (la JVM está habilitada de forma predeterminada)
Ver velocidad de ejecución
Desactivar el análisis de escape
Ver velocidad de ejecución
Los resultados de la prueba muestran que habilitar el análisis de escape tiene un gran impacto en el rendimiento de ejecución del código. Entonces, ¿por qué hay tal impacto?
Análisis de escape
Si el objeto analizado por escape se puede asignar en la pila, entonces el ciclo de vida del objeto sigue el hilo y no se requiere la recolección de basura. Si este método se llama con frecuencia, el rendimiento se puede mejorar considerablemente.
Después de adoptar el análisis de escape, los objetos que satisfacen el escape se asignan en la pila.
El análisis de escape no está habilitado y los objetos se asignan en el montón, lo que con frecuencia desencadenará la recolección de basura (la recolección de basura afectará el rendimiento del sistema), lo que resulta en una ejecución lenta del código.
Verificación de código
Habilitar el registro de impresión de GC
-XX: + ImprimirGC
Activar el análisis de escape
Puede ver que no hay registro de GC
Desactivar el análisis de escape
Se puede ver que el análisis de escape está desactivado y la JVM realiza la recolección de basura (GC) con frecuencia. Es esta operación la que causa una gran diferencia en el rendimiento.
para resumir
JVM es algo que a muchos entrevistadores les gusta preguntar. Pero las preguntas de algunos entrevistadores son muy complicadas, porque la JVM tiene un sistema de conocimiento amplio y profundo, por lo que si no está seguro, no debe responderlas a la ligera. Algunos conocimientos requieren práctica para experimentarlos, explicar con calma estos puntos de conocimiento le permitirá tomar la iniciativa en la entrevista.