JVM - 运行时数据区域

news2024/11/24 3:44:23

文章目录

  • 程序计数器
  • 方法区
  • 知识延申 -- 字符串常量池

程序计数器

并发情况下,会发生线程之间的上下文切换,当 线程1 的CPU时间片用完后,需要程序计数器记录 线程1 的下一条JVM指令的地址,等下一次 线程1 继续运行的时,才能从正确的位置开始继续执行

程序计数器是线程私有的 , 既 一个线程计数器 记录一个 线程 的指令位置

而且程序计数器是运行时数据区域唯一一个不存在内存溢出的区域

线程是什么?实际上可以理解为线程就是一个栈

线程调用方法 就是复制方法入栈的过程

方法入栈后就会形成栈帧

比如下面的一段代码

public class JvmDemo {
    public static void main(String[] args) {
        System.out.println("开始");
        func();
        System.out.println("结束");
    }  
    public static void func(){
    }   
}

执行该程序会创建一个主线程,然后main方法入栈,示意图如下

在这里插入图片描述
接着mian方法执行到 func(); ,就会复制一份 func 方法入栈,如下

在这里插入图片描述
func方法执行完后出栈,如下

在这里插入图片描述
最后mian方法再出栈

我们说线程可以简单的认为就是栈,所以也很明显,栈是线程私有的

栈的容量有限,如果我们不断调用方法入栈,就会导致栈溢出 ( 比如递归时没有递归出口 )

栈分为 虚拟机栈本地方法栈

可以简单理解为 :
-入栈的方法由 java 语言编写 的为虚拟机栈
-入栈的方法由 C语言编写 的为本地方法栈

Object类中有很多本地方法,比如反射中用到的 public final native Class<?> getClass(); ,添加了native 关键字,使用C语言编写,为了能直接对接操作系统

关于栈的几个问题:

  1. 垃圾回收是否涉及栈内存? 不涉及 ,因为栈帧执行完就会自动出栈,无需垃圾回收
  2. 栈内存是否分配越大越好吗?错误 ,物理内存大小一定,栈内存越大,能同时纯在的栈就会越少,既 线程数会越少
  3. 方法内的局部变量是否是线程安全的? 是线程安全的,线程调用方法是复制方法入栈,所以每个线程都有自己的方法副本,也就有了自己的局部变量副本,所以在操作时,不会受到其他线程的干扰

堆 – 存储对象实例

比如下面代码

public class JvmDemo {
    public static void main(String[] args) {
        Person person = new Person();
    }
}

class Person{}

其在内存中的模型如下
在这里插入图片描述
person引用存在main方法的栈帧中,而person实例对象存在于堆区中

堆区是所有线程共享的 ,比如

public class JvmDemo {
    public static void main(String[] args) {
        Person person = new Person();
        Thread thread01=new Thread(()->{
            Person person01 = new Person();
        });
        thread01.start();
    }
}

class Person{}

则内存模型如下,为了突出重点,省略 thread01 引用和实例对象 在内存中的展示,以及 thread01.start(); 的调用过程
在这里插入图片描述
堆的内存有限,不能无限创建对象实例,否者会堆内存溢出

因此JVM存在堆区的垃圾回收机制,清除垃圾对象,垃圾对象 可以简单定义为没有引用指向的实例对象

比如

Person person = new Person;
person = new Person;

此时就没有引用指向第一个new出来的对象,那么它就会被垃圾回收

存在堆区中的对象实例是线程间共享的,对象中的 全局变量 需要考虑线程安全问题

比如

public class JvmDemo {
    public static void main(String[] args) throws InterruptedException {
        Person person = new Person();
        Thread thread01=new Thread(()->{
            for (int i=0;i<100000;i++){
                person.money++;
            }
        });
        thread01.start();
        for (int i=0;i<100000;i++){
            person.money++;
        }
        thread01.join();
        System.out.println(person.money);
    }
}
class Person{
    public int money=0;
}

输出的结果不一定是200000
在这里插入图片描述

方法区

方法区 – 存储 类信息静态变量、方法

在 jdk 1.8之前,方法区存在于JVM内存中,其实现方法被称为 永久代;jdk 1.8及之后,方法区从JVM内存移出到本地内存,其实现方法被称为 元空间

方法区是线程共享的,因此多个线程修改同一个类的静态变量的时候同样存在线程安全问题,比如

public class JvmDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread01=new Thread(()->{
            for (int i=0;i<100000;i++){
                Person.money++;
            }
        });
        thread01.start();
        for (int i=0;i<100000;i++){
            Person.money++;
        }
        thread01.join();
        System.out.println(Person.money);
    }
}
class Person{
    public static int money=0;
}

输出结果同样不一定是200000,此处建议先学习一下什么是静态变量

方法区同样存在内存溢出的问题

知识延申 – 字符串常量池

JVM中还有一个特殊又重要的区域,就是 字符串常量池(StringTable),可以参考我的另外一篇博客

【Java 基础】你真的会用 String 吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/785743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【FPGA】Verilog:模块化组合逻辑电路设计 | 半加器 | 全加器 | 串行加法器 | 子模块 | 主模块

前言&#xff1a;本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载 示例&#xff1a;加法器 ​ 功能特性&#xff1a; 采用 Xilinx Artix-7 XC7A35T芯片 配置方式&#xff1a;USB-JTAG/SPI Flash 高达100MHz 的内部时钟速度 存储器&#xff1a;2Mbi…

重新成为合伙人背后,阿里需要蒋凡

监制 | 何玺 排版 | 叶媛 7月21日&#xff0c;阿里巴巴集团发布2023财年年报。据财报信息显示&#xff0c;阿里国际数字商业集团CEO蒋凡和菜鸟集团CEO万霖已成为阿里合伙人。 01 蒋凡重新成为阿里合伙人 该财报数据显示&#xff0c;截至3月31日的2023财年&#xff0c;阿里巴…

JAVA面试总结-Redis篇章(一)——缓存穿透

JAVA面试总结-Redis篇章&#xff08;一&#xff09; Redis缓存穿透解决方案一:缓存空数据&#xff0c;查询返回的数据为空&#xff0c;仍把这个空结果进行缓存![在这里插入图片描述](https://img-blog.csdnimg.cn/157c22930bff43cda2d325978a5ae05b.png)解决方案二&#xff1a;…

UE4/5C++多线程插件制作(十六、Coroutines协程封装)

我们要对协程继续封装制作: 协程是一种计算机程序组件,它允许在某个位置暂停执行,然后在稍后的时间点恢复执行。与传统的函数调用不同,协程可以被多次调用并且能够保留其内部状态,从而允许程序在执行到一定点时暂停,执行其他任务,然后再返回协程继续执行。 在传统的线…

机器学习深度学习——softmax回归(上)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——线性回归的简洁实现 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所…

CSS动画@animationend

CSS动画 是什么&#xff1f; CSS 中的动画类似于 flash 中的逐帧动画&#xff0c;表现细腻并且非常灵活&#xff0c;使用 CSS 中的动画可以取代许多网页中的动态图像、Flash 动画或者 JavaScript 实现的特殊效果。 这里感兴趣的可以去了解针 动画是什么 常用的css动画属性 :…

C国演义 [第十一章]

第十一章 有效的字母异位词题目理解代码 两数之和题目理解(暴力篇)代码题目理解(哈希篇)代码 有效的字母异位词 力扣链接 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;…

华为盘古大模型:能源领域的颠覆性突破

近日&#xff0c;华为盘古大模型在能源领域横空出世&#xff0c;引发了广泛关注和期待。作为一项具有颠覆性影响的技术创新&#xff0c;华为盘古大模型在能源行业中展现出巨大的潜力和前景。其优质的计算能力和智能优化算法&#xff0c;将为能源产业带来翻天覆地的变革。 盘古大…

linxu部署项目(详细教程)

首先我们需要一台虚拟机或者云服务器&#xff08;二选一即可&#xff09; 我们需要在安装jdk与tomcat 安装jdk&#xff0c;去官网下载对应的tar.gz压缩包就行tomcat同理 这里&#xff0c;我们已将下载好的JDK源码包 jdk-8u131-linux-x64.tar.gz 拷贝至 /usr/local/java/ 目录。…

《零基础入门学习Python》第066讲:GUI的终极选择:Tkinter3

今天我们一起来学习三个组件&#xff1a;Checkbutton、Radiobutton 和 LabelFrame。 同样&#xff0c;我们还是通过案例来讲解。 一、Checkbutton Checkbutton&#xff08;多选框&#xff09;。大家都知道什么叫做“翻牌子”&#xff0c;今天的第一个例子就是来写一个翻牌子…

如何清除Linux密钥环

如何清除Linux密钥环 Linux系统密钥环是什么如何清除密钥环方法一方法二 说明 最近使用Linux系统电脑&#xff0c;启动VScode总是弹出解锁密钥环的弹窗&#xff0c;单击取消后还会反复弹出&#xff0c;需要取消三次&#xff0c;但是如果没有及时取消会导致电脑卡机&#xff0c;…

Appium+python自动化(二十二)- 控件坐标获取(超详解)

简介 有些小伙伴或者是童鞋可能会好奇会问上一篇中的那个monkey脚本里的坐标点是如何获取的&#xff0c;不是自己随便蒙的猜的&#xff0c;或者是自己用目光或者是尺子量出来的吧&#xff0c;答案当然是&#xff1a;NO。获取控件坐标点的方式这里宏哥给小伙伴们分享和讲解三种方…

安全第一天

1. 编码 1.1 ASCLL编码 ASCII 是基于拉丁字母的一套电脑编码系统&#xff0c;主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准&#xff0c;并等同于国际标准ISO/IEC 646。 1.2 URL编码 URL&#xff1a;&#xff08;统一资源定位器、定位地址&#xff0c;俗称网页…

数据结构【图】

第六章 图 一、图 1.定义&#xff1a;V是顶点集&#xff0c;E是边集&#xff1b;|V|表示顶点数&#xff0c;称为阶&#xff1b;|E|表示边数&#xff1b;有向图叫弧<>&#xff0c;无向叫边&#xff08;&#xff09; &#xff1b; 有向图&#xff1a;有方向&#xff0c;&…

Yarn与Zookeeper学习

YARN学习 1.YARN是什么&#xff1f; yarn 分配运行资源 mapReduce的运行平台 2.YARN运行过程&#xff1a; 客户端与ResourceManager交互&#xff0c;生成临时配置文件(Application)ResourceManager根据Application信息生成Task然后生成MapReduceApplicationMaster(简称AM)AM…

python单元测试unittest实例详解

这篇文章主要介绍了python单元测试unittest用法,以实例形式详细分析了Python中单元测试的概念、用法与相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了python单元测试unittest用法。分享给大家供大家参考。具体分析如下&#xff1a; 单元测试作为任何…

用R语言来进行ababoost模型的构建

每天进步一点点&#xff0c;今天来分享怎么用R语言来进行ababoost模型的构建。 首先&#xff0c;什么是adaboost模型呢&#xff1f;它是一种迭代算法&#xff0c;属于boosting这个大类别的一员。它的核心思想是针对同一个训练集训练不同的分类器(弱分类器)&#xff0c;然后把这…

力扣题库刷题笔记118--杨辉三角

1、Python代码如下&#xff1a; 2、个人Python代码如下&#xff1a; 截图1的第5-9行和截图2的第5-6行均是生成一个元素均为1的杨辉三角。

1.前端入门

文章目录 一、基础认知1.1 认识网页&#xff1a;1.2 五大浏览器1.3 Web标准 总结 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、基础认知 1.1 认识网页&#xff1a; 1.网页由哪些部分组成&#xff1f; 文字、图片、音频、视频、超链接。 2.我们…

Spring Security从入门到精通

Spring Security从入门到精通&#xff08;学习三更老师的视频&#xff09; 视频地址&#xff1a;我觉得讲的不赖。三更老师的Spring Security视频 课程介绍 0. 简介 ​ Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;它提供…