JVM学习1:程序计数器、栈

JVM

JVM、JRE、JDK区别

在这里插入图片描述

JVM的作用

面试

理解底层的实现原理:字节码等等

中高级程序员的必备技能

JVM学习路线

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LQWo5Uow-1631876420437)(C:\Users\逍遥\AppData\Roaming\Typora\typora-user-images\image-20210914123953145.png)]

程序计数器

Program Counter Register程序计数器(寄存器)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EowtFlZp-1631876420442)(JVM.assets/image-20210914234554707.png)]

左边的是二进制字节码,这是跨平台的基础,都是jvm的指令。

还必须经过解释器,变成机器码,然后交给了CPU进行处理。

作用:

程序计数器的作用就是:记住下一条jvm指令 的执行地址。

等第一条指令在解释器解释完之后,3会放入到程序计数器中,解释器就会进去取,然后执行。就是记住下一条jvm指令的执行地址。

物理上,是通过寄存器实现的。寄存器是整个cpu里读取指令速度较快的。读取指令是非常频繁的,所以jvm中就把寄存器当做了程序计数器,进行jvm指令的执行地址的存放。

特点:

1、线程是私有的。

多个线程运行的时候,cpu会有一个调度器组件分配时间片,给线程1分配时间片,如果线程1没有执行完,就会把线程1 的状态暂存然后转到线程2去,开始执行线程2,然后等到线程2的时间片用完了,就开始转回到线程1去。如果恰好线程1执行到10(下一个要10,)记录到了程序计数器里面,要搞清楚程序计数器是私有的,是只属于线程1的,等开始转到线程2之后,就开始运行2的,然后转回1之后,就知道要开始运行10了,每个线程都有自己的程序计数器。

2、唯一一个不会存在内存溢出的区。

其他的一些区,堆栈、方法区等可能会存在内存溢出,而程序计数器不会存在内存溢出问题。

JVM Stacks 虚拟机栈

栈的概念就是类似弹夹,先进后出。

java中线程运行的时候,线程需要栈。栈:线程运行需要的内存空间。

栈是由栈帧组成。一个栈帧就对应一个方法的调用。

每个方法运行时需要的内存就是栈帧。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kMnK0mVV-1631876420447)(JVM.assets/image-20210915000246970.png)]

方法运行需要的内存:参数、局部变量、返回地址。都是需要占用内存的,所以每次方法运行时,需要预先分配好。

如果调用第一段方法时,把栈帧1放入,栈帧1调用了方法2(栈帧2,)然后栈帧2就放入了栈内。然后以此类推等到所有的调用都结束了,所有的栈帧都逐步出去。

定义

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-db0HymYx-1631876420450)(JVM.assets/image-20210915000626189.png)]
在这里插入图片描述

问题辨析:线程安全

1、垃圾回收是否涉及栈内存。

不涉及,垃圾回收只涉及堆内存。

2、栈内存分配越大越好吗?

不是,如果大了,会影响线程的数量,因为物理内存是有限的。

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

是。要观察这个线程是否对每个变量是否是私有的。局部变量是私有的。但如果把变量改成static成为了共享的就需要考虑线程安全,是私有的就不需要考虑线程安全。

一个线程对应一个栈,不同的线程会产生不同的栈帧,所以是安全的。

相当于每个线程都有自己的私有的栈帧。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UIWHdfKD-1631876420455)(JVM.assets/image-20210915162552896.png)]

这个sb是作为参数传进来,可能会有不同的线程同时在使用这个sb,已经不再是私有的了,所以要改掉。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Myx8DTwQ-1631876420457)(JVM.assets/image-20210915162644417.png)]

这个sb虽然是局部变量,但是是返回了sb,所以可能会被其他线程并发的执行,所以总的来说,要看一个变量是不是线程安全的,那么就要看清楚是不是逃离了这个方法的作用范围,如果逃离了就不是线程安全的了。方法内局部变量始终在方法内的话,就是线程安全的。

问题辨析:栈内存溢出

第一种情况是:栈帧过多导致栈内存溢出。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ff60DEpS-1631876420458)(JVM.assets/image-20210915163200179.png)]

方法递归调用没有设置正确的一个调用条件,就容易栈内内存溢出。

第二种情况是栈帧过大导致栈内存溢出。但这种情况比较少出现,一般是栈帧过多导致内存溢出。

错误名字是 stackoverflow。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XZcWVOf5-1631876420460)(JVM.assets/image-20210915174340093.png)]

可以提前设置好栈的总大小空间。

线程运行诊断

1、CPU占用过多。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b0TlsgUS-1631876420462)(JVM.assets/image-20210916001814956.png)]

2、程序运行很长时间没有结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员洲洲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值