JVM
java虚拟机
好处:
一次编写 到处运行
自动内存管理机制
数组下标越界检查
多态
比较:
jvm jre jdk
jre = jvm+基础类库
jdk = jre+编译工具
内存结构:
1.程序计数器
2.虚拟机栈
3.本地方法栈
4.堆
5.方法区
#程序计数器:记住下一条jvm指令的执行地址
物理上通过寄存器来实现的
特点:线程私有
唯一一个不会存在内存溢出的地方
#虚拟机栈:每个线程运行时需要的内存,称为虚拟机栈
每个栈(Fram)由多个栈帧组成
每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
1.垃圾回收不涉及栈内存
2.栈内存不是越大越好 引起线程数目变小
3.方法内局部变量如果没有逃离方法的作用访问 他就是线程安全的
栈内存溢出
1.栈帧个数过多
2.栈帧过大
线程运行诊断
1.CPU占用过多
top只能查看进程对CPU的占用情况 无法查看线程对CPU占用的情况
ps H pid进程号 tid 线程号%cpu cpu占用情况 |grep 32655过滤
用top定位哪个进程对CPU占用过高
ps H -eo pid tid %cpu|grep 用ps命令进一步定位是哪个线程引起的问题
jstack 进程id 转换进制
2.程序运行时间很长都没有结果
jstack 进程id find one java-定位死锁位置
#本地方法栈
#堆Heap
通过New关键字,创建对象都会使用堆内存
特点:
线程共享,堆中对象都需要考虑线程安全的问题
有垃圾回收机制
堆内存溢出:
不断产生新对象 并一直使用他
#方法区
线程共享
方法区内存溢出:
1.8之前会导致永久代内存溢出
1.8之后会导致元空间内存溢出
运行时常量池:常量池是。class文件中的,当该类被加载,他的常量信息就会放入运行时常量池 并把里面的符号地址编程真实地址
常量池:常量池就是一张表,虚拟机根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息