Pila de máquinas virtuales JVM en profundidad

definición

Sracks de máquina virtual Java (pila de máquina virtual Java)

  • La memoria requerida para que se ejecute cada subproceso se denomina pila de máquina virtual
  • Cada pila se compone de varios marcos de pila (Frame), correspondientes a la memoria ocupada por cada llamada al método
  • Cada subproceso solo puede tener un marco de pila activo, correspondiente al método que se está ejecutando actualmente

Nota:

  1. El mecanismo de recolección de basura no involucra la memoria de la pila, porque la memoria de la pila se recicla automáticamente después de cada llamada al método.
  2. La asignación de memoria de la pila no es cuanto más grande, mejor
  3. ¿Las variables locales en los métodos son seguras para subprocesos?
  • Si no se accede a las variables locales en el método desde el rol del método, su hilo es seguro
  • Si es una variable local que se refiere a un objeto y escapa del método de acción, se debe considerar la seguridad de los subprocesos.

Desbordamiento de memoria de pila

Demasiados marcos de pila provocan un desbordamiento de la memoria de pila

Código de muestra: el método recursivo no aumenta la condición final

public class demo {
    
    
    private static int count;
    public static void main(String[] args) {
    
    
        try {
    
    
            run1();
        }catch (Throwable throwable){
    
    
            throwable.printStackTrace();
            System.out.println(count);
        }
    }
    public static void run1(){
    
    
        count++;
        run1();
    }
}

Inserte la descripción de la imagen aquí

Un tamaño de marco de pila excesivo provoca un desbordamiento de la memoria de la pila

Código de muestra: referencia bidireccional de conversión de datos Json

import org.codehaus.jackson.map.ObjectMapper;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class demo2 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //创建一个部门对象
        Dept dept = new Dept();
        dept.setDname("Market");
        //创建两个员工对象
        Emp emp1 = new Emp();
        Emp emp2 = new Emp();
        emp1.setEname("张三");
        emp1.setDname(dept);
        emp2.setEname("李四");
        emp2.setDname(dept);
        dept.setEmpList(Arrays.asList(emp1,emp2));
        System.out.println(new ObjectMapper().writeValueAsString(dept));
    }
}

class Emp {
    
    
    private String ename;
    private Dept dname;

    public Emp() {
    
    
    }

    public String getEname() {
    
    
        return ename;
    }

    public void setEname(String ename) {
    
    
        this.ename = ename;
    }

    public Dept getDname() {
    
    
        return dname;
    }

    public void setDname(Dept dname) {
    
    
        this.dname = dname;
    }

    public Emp(String ename, Dept dname) {
    
    
        this.ename = ename;
        this.dname = dname;
    }
}

class Dept{
    
    
    private String dname;
    private List<Emp> empList;

    public Dept() {
    
    
    }

    public String getDname() {
    
    
        return dname;
    }

    public void setDname(String dname) {
    
    
        this.dname = dname;
    }

    public List<Emp> getEmpList() {
    
    
        return empList;
    }

    public void setEmpList(List<Emp> empList) {
    
    
        this.empList = empList;
    }

    public Dept(String dname, List<Emp> empList) {
    
    
        this.dname = dname;
        this.empList = empList;
    }
}

Inserte la descripción de la imagen aquí

Diagnóstico de ejecución de subprocesos

Caso 1: CPU ocupa demasiado (en el sistema operativo Linux)

/**
 * 演示 cpu 占用过高
 */
public class Demo1_16 {
    
    

    public static void main(String[] args) {
    
    
        new Thread(null, () -> {
    
    
            System.out.println("1...");
            while(true) {
    
    

            }
        }, "thread1").start();


        new Thread(null, () -> {
    
    
            System.out.println("2...");
            try {
    
    
                Thread.sleep(1000000L);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }, "thread2").start();

        new Thread(null, () -> {
    
    
            System.out.println("3...");
            try {
    
    
                Thread.sleep(1000000L);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }, "thread3").start();
    }
}

  1. Utilice top para localizar qué proceso ocupa demasiada cpu
  2. Luego use el comando ps para ubicar con más detalle qué subproceso causó que la CPU ocupara un valor demasiado alto de
    ps H -eo pid, tid,% cpu | grep id del proceso
  3. Enumere todos los subprocesos del proceso de acuerdo con el id del proceso: id del proceso jstack
  4. Convierta la identificación del hilo del hilo encontrado en hexadecimal, puede encontrar el problema específico en la lista

Caso 2: el programa se ejecuta durante mucho tiempo sin resultados

package cn.itcast.jvm.t1.stack;

/**
 * 演示线程死锁
 */
class A{
    
    };
class B{
    
    };
public class Demo1_3 {
    
    
    static A a = new A();
    static B b = new B();


    public static void main(String[] args) throws InterruptedException {
    
    
        new Thread(()->{
    
    
            synchronized (a) {
    
    
                try {
    
    
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                synchronized (b) {
    
    
                    System.out.println("我获得了 a 和 b");
                }
            }
        }).start();
        Thread.sleep(1000);
        new Thread(()->{
    
    
            synchronized (b) {
    
    
                synchronized (a) {
    
    
                    System.out.println("我获得了 a 和 b");
                }
            }
        }).start();
    }

}

Supongo que te gusta

Origin blog.csdn.net/zh2475855601/article/details/114583181
Recomendado
Clasificación