- 程序计数器只是逻辑上的概念,我们通常采用寄存器来充当一个程序计数器
- 因为寄存器的读取速度是最快的,我们可以快速保存并且读出物理地址位置来进行交互
栈简介我们首先来回顾栈的概念:
![JVM学习笔记——内存结构篇](http://shimg.jingyanzongjie.com/230727/135R13223-3.png)
文章插图
我们的栈先进后出,用于存储程序中的部分信息
虚拟机栈简介我们的虚拟机栈和栈的基本原理相同,但存储的东西就不尽相同了:
- 虚拟机栈也是绑定线程的,每个线程有且仅有一个虚拟机栈
- 虚拟机栈中存储着栈帧,可以存在有多个栈帧,栈帧就是每个方法运行时所需要的内存
- 每个线程运行时所需要的内存,称为虚拟机栈
- 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
- 每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存
package cn.itcast.jvm.t1.stack;/** * 演示栈帧 */public class Demo1_1 {public static void main(String[] args) throws InterruptedException {method1();method3();}private static void method1() {method2(1, 2);}private static int method2(int a, int b) {int c =a + b;return c;}private static int method3() {return 1;}}
我们进行简单的介绍:- 这个程序就是一个线程
- 这三个方法分别就对应着一个栈帧
- 我们调用main,mian进入栈,main中又调用method1,method1进入栈,method1调用method2,所以method2进入栈
- 注意我们的method3不包含在method1的循环中,所以我们会先将前置栈帧都排除后,然后在main栈帧的上方进行累加method3
![JVM学习笔记——内存结构篇](http://shimg.jingyanzongjie.com/230727/135R14114-4.png)
文章插图
虚拟机栈问题解释我们针对虚拟机栈提出了三个问题,下面进行解释:
- 垃圾回收是否会涉及栈内存
/*答案是:否,因为栈是属于线程内内存,栈具有自动回收功能*/
- 栈内存是否是越大越好
/*答案是:否,如果jvm设置的内存过大,就会导致其它程序所占用的内存小 。*/
- 方法内的局部变量是否线程安全
/**答案是:根据实际情况而定,我们通过判断作用范围来进行线程安全判断首先我们需要介绍两个词汇:- StringBuffer 用于多线程,保证多线程安全,但效率较慢- StringBuilder 用于单线程,无法保证但线程安全,效率较快**/// 我们下面给出一个简单示例:// 示例1:下面的变量x是属于方法中的变量,属于局部变量,因此不会出现线程安全问题package cn.itcast.jvm.t1.stack;/** * 局部变量的线程安全问题 */public class Demo1_18 {// 多个线程同时执行此方法static void m1() {int x = 0;for (int i = 0; i < 5000; i++) {x++;}System.out.println(x);}}// 示例2:下面我们通过StringBuilder来进行安全问题测试(因为StringBuilder不具有线程安全保护)// m1:StringBuilder创建在方法内部,也只在方法内部使用,属于局部变量,不具有线程安全问题// m2:StringBuilder来自于外部,变量作用范围越界,具有线程安全问题// m3:StringBuilder返回至外部,变量作用范围越界,具有线程安全问题package cn.itcast.jvm.t1.stack;/** * 局部变量的线程安全问题 */public class Demo1_17 {public static void main(String[] args) {StringBuilder sb = new StringBuilder();sb.append(4);sb.append(5);sb.append(6);new Thread(()->{m2(sb);}).start();}public static void m1() {StringBuilder sb = new StringBuilder();sb.append(1);sb.append(2);sb.append(3);System.out.println(sb.toString());}public static void m2(StringBuilder sb) {sb.append(1);sb.append(2);sb.append(3);System.out.println(sb.toString());}public static StringBuilder m3() {StringBuilder sb = new StringBuilder();sb.append(1);sb.append(2);sb.append(3);return sb;}}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 【lwip】08-ARP协议一图笔记及源码实现
- 用一台笔记本电脑如何赚钱(笔记本电脑赚钱的办法)
- 小米笔记本Pro15增强版评测_小米笔记本Pro15增强版评测表现
- 笔记本电脑CF中烟雾头怎么调(win10cf新版本烟雾保护头怎么调)
- 笔记本电脑配置高低怎么区分(笔记本电脑看什么配置判断好坏)
- 四 【单片机入门】应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及中断的使用
- pytorch、paddlepaddle等环境搭建 深度学习环境搭建常用网址、conda/pip命令行整理
- 三十九 Java开发学习----SpringBoot整合mybatis
- 2023年圣诞节学习运有所提升的星座智慧多多成绩提升
- 电脑开不了机怎么办简单方法(笔记本电脑开不了机)