jvm栈
1.栈的概念
jvm栈的英文全称是(Java virtual machine stacks)一个栈由多个栈帧组成,一个线程,对应着一个栈,如果是多个线程,就对应多个虚拟机栈,
栈帧是每个方法运行时需要的内存,栈帧是一个个的方法组成的,所以线程运行的时候,每个方法需要的内存称之为一个栈帧
1.1栈跟栈帧之间的调用(先入后出)结合下图观看
当我调用第一个方法时,栈会给第一个方法分配一个栈帧空间,并把他放入栈的底部。当这个方法执行完了,就会把对应的栈帧出栈,释放这个方法所占用的内存。
1.1.1入栈
一个栈内是可以有多个栈贞的,比如调用了方法1,那么这个栈帧就会被放入到栈里,然后这个方法1又调用了方法2,方法2就会产生一个新的栈帧,然后放入到栈中,方法2又调用了方法3,那么就会让方法3也会产生栈帧内存,放入栈内。
1.1.2出栈
方法3调用结束的时候,就会把栈帧3的内存释放掉,然后回到方法2,方法2调用结束后,他就会把方法2占用的栈帧内存释放掉并出栈,最后方法1执行完毕后也把方法1占用的栈帧内存释放并出栈。
每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法。活动栈帧就是在栈的顶部的正在执行的方法。
2.示例代码
2.1
首先调用main方法,去栈内开辟空间,将main方法放入到了栈的底部,生成了main方法的栈帧(也就是上面的方法一),然后调用方法二,方法3,调用完毕后释放内存,依次放出
3.问题辨析
3.1垃圾回收是否涉及栈内存
垃圾回收不涉及栈内存,因为栈所占用的内存较小而且每次出栈的时候都将内存释放了
3.2栈内存分配越大越好吗?
栈内存的大小不会影响方法执行的速度,而且由于计算机硬件的储存大小是有限的,栈内存分配越大,会导致最大线程数减少,得不偿失.
3.3方法内的局部变量是否线程安全?
当x是方法内的局部变量,一个线程对应一个栈,线程内每一次方法调用都会产生一个新的栈帧,比如线程1调用这个方法,那么他就会在栈1里开栈帧1,线程2同理,两个线程互不干扰,所以,在这个例子里是不会有线程安全问题
如果这个变量改成static变量,结果就会大不一样了。
因为这样的话就相当于共享了。如果是共享的,就要考虑线程安全问题,不是共享的,每个线程私有的就不需要考虑线程安全了。
3.3.1总结
看一个变量是否线程安全,不仅要看他是不是方法内的局部变量,还要看他是否逃离了这个方法的作用范围,如果这个变量作为返回值逃离了这个方法的作用范围,那他就有可能被其他方法访问到,那么线程就不安全了