JVM(1)

43 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第24天,点击查看活动详情

什么是JVM

定义: Java Virtual Machine - java 程序的运行环境(java 二进制字节码的运行环境) 好处:

  • 一次编写,到处运行
  • 自动内存管理,垃圾回收功能
  • 数组下标越界检查
  • 多态

JVM内存结构

1. 程序计数器

  • 作用:记住下一条JVM指令的执行地址

  • 特点:

    • 线程私有
    • 不会存在内存溢出

使用CPU中的寄存器作为程序计数器:特点:速度快

Java源代码->二进制字节码(通过解释器)->机器码->CPU

2. 虚拟机栈

多线程中有过栈与栈帧相关概念

栈-线程运行需要的内存空间

栈帧-每个方法运行时需要的内存空间

  • 每个线程运行时所需要的内存,称为虚拟机栈
  • 每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存
  • 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

问题辨析

  • 垃圾回收是否涉及栈内存?

回答:不涉及,栈在每一次调用后会自动回收

  • 栈内存分配越大越好吗?

不是,加大反而会减少多线程数量,加大仅仅可以增加方法调用的次数

  • 方法内的局部变量是否线程安全?

回答:如果方法内局部变量没有逃离方法的作用访问,它是线程安全的

如果是局部变量引用了对象,并逃离方法的作用范围(也就是引用类型作为返回值返回了),需要考虑线程安全

2.2 栈内存溢出

  • 栈帧过多导致栈内存溢出
  • 栈帧过大导致栈内存溢出

2.3 线程运行诊断

案例1: cpu 占用过多

定位

  • 用top定位哪个进程对cpu的占用过高

  • ps H -eo pid,tid,%cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)

  • jstack 进程id

    • 可以根据线程id 找到有问题的线程,进一步定位到问题代码的源码行号,得将十进制变为十六进制

案例2:程序运行很长时间没有结果

多线程发生了死锁