学习路线
作用:记住下一条jvm指令的执行地址
特点
- 线程私有的
- 唯一不会存在内存溢出的区域
Java源代码->二进制字节码(jvm指令)->【解释器解释】机器码->CPU执行
2、虚拟机栈(线程私有) 2.1定义栈:线程运行时需要的内存空间
栈帧:每个方法运行时需要的内存,栈由多个栈帧组成
每个线程只能有一个活动的栈帧,对应着当前正在执行的那个方法
栈的演示public class test {
public static void main(String[] args) {
m1();
}
public static void m1(){
m2(1,2);
}
public static int m2(int a,int b){
int c = a + b;
return c;
}
}
问题辨析
1、垃圾回收是否涉及栈内存?
不需要!栈帧出栈的时候就已经释放掉了
2、栈内存分配越大越好吗?
不是!栈内存太大反而影响到线程数目,采用系统默认的大小即可
3、方法内的局部变量是否线程安全?
如果方法内部局部变量没有逃离方法的作用范围,它是线程安全的
如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全
- 栈帧过多(递归调用)
- 栈帧过大
-Xss256k
2.3线程运行诊断案例1:CPU占用过多
-
用top定位哪个进程对CPU的占用高
top
-
用ps命令进一步定位是哪个线程引起的CPU占用过高(显示的线程是10进制)
ps -H -eo pid,tid,%cpu | grep 进程id
-
用jstack工具将进程中的所有线程列出来(显示的线程id是16进制,因此查找问题的时候需要先将上一步查到的线程id换算成16进制),可以根据线程id找到有问题的线程,进一步定位到有问题的代码行数
jstack 进程id
案例2:程序运行很长时间没有结果
jstack 进程id3、本地方法栈 4、堆 5、方法区



