JVM - 运行时数据区域

文章目录

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

程序计数器

并发情况下,会发生线程之间的上下文切换,当 线程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 吗?

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TCP/IP协议详解(二)

目录内容 TCP协议的可靠性 TCP的三次握手 TCP的四次挥手 C#中&#xff0c;TCP/IP建立 三次握手和四次挥手常见面试题 在上一篇文章中讲解了TCP/IP的由来以及报文格式&#xff0c;详情请见上一篇文章&#xff0c;现在接着来讲讲TCP/IP的可靠性以及通过代码的实现。 在TCP首部的…

layui框架学习(33:流加载模块)

Layui中的流加载模块flow主要支持信息流加载和图片懒加载两部分内容&#xff0c;前者是指动态加载后续内容&#xff0c;示例的话可以参考csdn个人博客主页&#xff0c;鼠标移动到页面底部时自动加载更多内容&#xff0c;而后者是指页面显示图片时才会延迟加载图片信息。   fl…

Excel的使用

1.EXCEL诞生的意义 1.1 找到想要的数据 1.2 提升输入速度 2.数据分析与可视化操作 目的是提升数据的价值和意义 3.EXCEL使用的内在意义和外在形式 4.EXCEL的价值 4.1 解读及挖掘数据价值 4.2 协作板块 4.3 展示专业度 4.4 共享文档内容 5.人的需求》》软件功能

Stephen Wolfram:神经网络

Neural Nets 神经网络 OK, so how do our typical models for tasks like image recognition actually work? The most popular—and successful—current approach uses neural nets. Invented—in a form remarkably close to their use today—in the 1940s, neural nets …

Linux安装MySQL 8.1.0

MySQL是一个流行的开源关系型数据库管理系统&#xff0c;本教程将向您展示如何在Linux系统上安装MySQL 8.1.0版本。请按照以下步骤进行操作&#xff1a; 1. 下载MySQL安装包 首先&#xff0c;从MySQL官方网站或镜像站点下载MySQL 8.1.0的压缩包mysql-8.1.0-linux-glibc2.28-x…

ChatGPT和搜索引擎哪个更好用

目录 ChatGPT和搜索引擎的概念 ChatGPT和搜索引擎的作用 ChatGPT的作用 搜索引擎的作用 ChatGPT和搜索引擎哪个更好用 总结 ChatGPT和搜索引擎的概念 ChatGPT是一种基于对话的人工智能技术&#xff0c;而搜索引擎则是一种用于在互联网上查找和检索信息的工具。它们各自具…

93.qt qml-自定义Table优化(新增:水平拖拽/缩放自适应/选择使能/自定义委托)

之前我们更新了90.qt qml-Table表格组件(支持表头表尾固定/自定义颜色/自定义操作按钮/排序)_qml 表格_诺谦的博客-CSDN博客 但是一直没出源码,是因为该demo还存在问题,那就是表头表尾固定下,如果是半透明状态下,会看到表头表尾固定后的内容,所以只能重构代码,不能使用重…

2.1、修改Gitea上传附件大小限制

目录 1. 修改Gitea配置2. 重启服务3. 使用 之前在Gitea上传附件时&#xff0c;显示大小超过3MB&#xff0c;不能符合我的使用场景。记录一下修改这个限制的配置。 1. 修改Gitea配置 默认在安装路径的custom/conf/app.ini文件中&#xff1a; 添加参数 [repository.upload] ; 是…

Android 面试题 内存泄露的原因 二

&#x1f525; 什么是内存泄漏 &#x1f525; 在Android开发过程中&#xff0c;当一个对象已经不需要再使用了&#xff0c;本该被回收时&#xff0c;而另个正在使用的对象持有它引用从而导致它不能被回收&#xff0c;这就导致本该被回收的对象不能被回收而停留在堆内存中&#…

深度学习:常用优化器Optimizer简介

深度学习&#xff1a;常用优化器Optimizer简介 随机梯度下降SGD带动量的随机梯度下降SGD-MomentumSGDWAdamAdamW 随机梯度下降SGD 梯度下降算法是使权重参数沿着整个训练集的梯度方向下降&#xff0c;但往往深度学习的训练集规模很大&#xff0c;计算整个训练集的梯度需要很大…

基于应用值迭代的马尔可夫决策过程(MDP)的策略的机器人研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【数据结构】栈(Stack)的实现 -- 详解

一、栈的概念及结构 1、概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在表尾进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出 LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈…

音视频——视频流H264编码格式

1 H264介绍 我们了解了什么是宏快&#xff0c;宏快作为压缩视频的最小的一部分&#xff0c;需要被组织&#xff0c;然后在网络之间做相互传输。 H264更深层次 —》宏块 太浅了 ​ 如果单纯的用宏快来发送数据是杂乱无章的&#xff0c;就好像在没有集装箱 出现之前&#xff0c;…

abp vnext4.3版本托管到iis同时支持http和https协议

在项目上本来一直使用的是http协议,后来因为安全和一些其他原因需要上https协议&#xff0c;如果发布项目之后想同时兼容http和https协议需要更改一下配置信息&#xff0c;下面一起看一下&#xff1a; 1.安装服务器证书 首先你需要先申请一张服务器证书&#xff0c;申请后将证…

【JavaEE初阶】Tomcat安装与使用及初识Servlet

文章目录 1. Tomcat的安装与使用1.1 Tomcat安装1.2 Tomcat的启动1.3 Tomcat部署前端页面 2. Servlet2.1 Servlet是什么2.2 第一个Servlet程序2.3 常见错误 1. Tomcat的安装与使用 1.1 Tomcat安装 在浏览器中搜索Tomcat,打开官方网页.Tomcat官网 点击下载Tomcat8. 点击下载压…

OceanMind海睿思获评中国信通院“内审数字化产品评测”卓越级(最高级)!

2023年7月27日&#xff0c;由中国内部审计协会、中国通信标准化协会指导&#xff0c;中国信息通信研究院主办的第二届数字化审计论坛在北京成功召开。 大会聚焦内部审计数字化领域先进实践、研究成果、行业发展举措&#xff0c;重磅发布了多项内部审计数字化领域的最新研究和实…

《TCP IP网络编程》第十三章

第 13 章 多种 I/O 函数 13.1 send & recv 函数 Linux 中的 send & recv&#xff1a; send 函数定义&#xff1a; #include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags); /* 成功时返回发送的字节数&#xff0c;失败…

pytorch的发展历史,与其他框架的联系

我一直是这样以为的&#xff1a;pytorch的底层实现是c(这一点没有问题&#xff0c;见下边的pytorch结构图),然后这个部分顺理成章的被命名为torch,并提供c接口,我们在python中常用的是带有python接口的&#xff0c;所以被称为pytorch。昨天无意中看到Torch是由lua语言写的&…

iOS - Apple开发者账户添加新测试设备

获取UUID 首先将设备连接XCode&#xff0c;打开Window -> Devices and Simulators&#xff0c;通过下方位置查看 之后登录(苹果开发者网站)[https://developer.apple.com/account/] &#xff0c;点击设备 点击加号添加新设备 填写信息之后点击Continue&#xff0c;并一路继续…

MCU全球生态发展大会|AT32 MCU加速应用创新与产业智慧升级

7月21日&#xff0c;由AspenCore主办的2023全球MCU生态发展大会在深圳罗湖君悦酒店圆满举行。本次活动聚集国际和本土知名MCU厂商的技术和应用专家&#xff0c;为来自消费电子、家电、工业控制、通信网络、新能源汽车和物联网领域的OEM厂商和方案集成商代表带来MCU领域的最新技…