Java虚拟机栈栈定义
- 每个线程运行时需要的内存,称为虚拟机栈
- 每个栈由多个栈帧组成,对应着每次方法调用时所占用的内存
- 每个线程只能由一个活动栈帧.对应着当前正在执行的方法
问题辨析
1 . 垃圾回收是否涉及栈内存?
- 不会,栈中会自己出栈,栈中没有垃圾回收
2 . 栈内存越大越好吗?
- 栈内存划分越大反而会使你的线程数越少,因为物理内存的大小是一定的,每个线程的栈内存多,会使得线程数目变少,不建议过大
3 . 方法内的局部变量是否线程安全?
- 如果没有逃离线程的作用范围(没有返回变量,也不和外面变量有一个联系等)或者是基本类型变量,则线程安全,每个线程都会是线程私有的局部变量,互不干扰;
- 如果是静态变量则会影响,所以如果是静态变量的话就要考虑线程安全的一个问题
- 如果不是基本变量并且逃离了线程的作用范围(有返回变量等),返回了局部变量被其他线程拿到了修改了也要注意线程安全的一个问题
栈内存溢出(StackOverflowError)
1 . 栈帧过多导致栈内存溢出
- 在递归中比较常见,递归如果没有一个正确的返回的话,就会栈帧越来越多,最后内存溢出
2 . 栈帧过大导致内存溢出
- 不容易出现,毕竟栈帧一般不会那么大
线程运行诊断
1 . cpu占用过多
- 定位
- 用
top
定位哪个进程对cpu占用高 ps H -eo pid,tid,%cpu | 进程id
(用ps命令进一步定位哪个线程占用cpu过高)jstack 进程id
(把10进制的线程id换算成16进制,查出java线程名称)- 找到java代码中的问题,修改
2 . 程序运行很长时间没有结果
jstck 进程id
(定位到死锁,找详细信息到几行代码)
本地方法栈(Native Method Stacks)
- JAVA调用的一些本地方法,由c++,c编写
- 例如Object的clone方法就是本地方法有一个
native
修饰protected native Object clone() throws CloneNotSupportedException;