当前位置: 首页 > news >正文

【JVM】JVM五大内存区域介绍

目录

 一、程序计数器(线程私有)

二、java虚拟机栈(线程私有)

2.1、虚拟机栈

2.2、栈相关测试

2.2.1、栈溢出

三、本地方法栈(线程私有)

四、java堆(线程共享)

五、方法区(线程共享)

六、实例演示


        Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。

 一、程序计数器(线程私有)

        程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里 [1] ,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
        由于Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

二、java虚拟机栈(线程私有)

2.1、虚拟机栈

        与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧 [1] (Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

        “栈”通常就是指这里讲的虚拟机栈,或者更多的情况下只是指虚拟机栈中局部变量表部分。
局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用
(reference类型,它并不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。
        这些数据类型在局部变量表中的存储空间以局部变量槽(Slot)来表示,其中64位长度的long和double类型的数据会占用两个变量槽,其余的数据类型只占用一个。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。请读者注意,这里说的“大小”是指变量槽的数量,虚拟机真正使用多大的内存空间(譬如按照1个变量槽占用32个比特、64个比特,或者更多)来实现一个变量槽,这是完全由具体的虚拟机实现自行决定的事情。

2.2、栈相关测试

2.2.1、栈溢出

测试类:

如果某个线程的线程栈的内存被耗尽,没有足够的内存资源去创建栈帧,就会发生内存溢出。

public class TestStack {public static void main(String[] args) {test();}public static void test(){test();}
}

结果:

        上面这串代码的执行过程是:线程先执行main方法,同时会创建main方法的栈帧插入到该线程的线程栈中,当执行到test()方法时,创建test()方法的栈帧插入到该线程的线程栈中,执行到test()方法里的test()方法时,创建栈帧,插入到线程栈中,后面进行不断创建栈帧、入栈。当创建一定数量的栈帧后,剩下的线程资源无法再创建新的栈帧就会报StackOverflowError异常(堆栈溢出异常)(当前虚拟机栈不可以动态扩展)

        如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。

三、本地方法栈(线程私有)

        本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。

四、java堆(线程共享)

        Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,Java世界里“几乎”所有的对象实例都在这里分配内存。

        Java堆是垃圾收集器管理的内存区域,因此一些资料中它也被称作“GC堆”(Garbage CollectedHeap)。从回收内存的角度看,由于现代垃圾收集器大部分都是基于分代收集理论设计的,所以Java堆中经常会出现“新生代”“老年代”“永久代”“Eden空间”“From Survivor空间”“To Survivor空间”等名词。

        如果从分配内存的角度看,所有线程共享的Java堆中可以划分出多个线程私有的分配缓冲区
(Thread Local Allocation Buffer,TLAB)
,以提升对象分配时的效率。不过无论从什么角度,无论如何划分,都不会改变Java堆中存储内容的共性,无论是哪个区域,存储的都只能是对象的实例,将Java堆细分的目的只是为了更好地回收内存,或者更快地分配内存。

        Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩展来实现的(通过参数-Xmx和-Xms设定)。如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。

五、方法区(线程共享)

        方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

        如果方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。

六、实例演示

1、基本数据类型

实体类

@Data
public class UserParam {/*** 用户名*/private String userName;/*** 密码*/private String password;/*** 昵称*/private String nickName;/*** 旧密码*/private String oldPassWord;/*** 新密码*/private String newPassWord;}

测试

public class TestStack {public static void main(String[] args) {UserParam userParam=new UserParam();int b=1;test(userParam,b);test(userParam,b);System.out.println(userParam);}public static void test(UserParam userParam,int a){userParam.setUserName(String.valueOf(a));a=2;}
}

结果:

分析:

b变量是基本数据类型,创建完在栈帧中,没有任何引用,参数也只是传入值,方法中a改变对b没有任何影响。

 2、引用数据类型会根据传入的引用数据的改变而改变

public class TestStack {public static void main(String[] args) {UserParam userParam=new UserParam();userParam.setNickName("张三");test(userParam);test(userParam);System.out.println(userParam);}public static void test(UserParam userParam){userParam.setUserName(userParam.getNickName());userParam.setNickName("李四");}
}

结果:

分析:

将对象作为参数传入时,test方法中的对象也是指向同一片内存区域,操作的是同一块内存,所以在test方法中改变属性的值会影响外边同一个对象内的属性值。

相关文章:

【JVM】JVM五大内存区域介绍

目录 一、程序计数器(线程私有) 二、java虚拟机栈(线程私有) 2.1、虚拟机栈 2.2、栈相关测试 2.2.1、栈溢出 三、本地方法栈(线程私有) 四、java堆(线程共享) 五、方法区&…...

自动驾驶感知系统--惯性导航定位系统

惯性导航定位 惯性是所有质量体本身的基本属性,所以建立在牛顿定律基础上的惯性导航系统(Inertial Navigation System,INS)(简称惯导系统)不与外界发生任何光电联系,仅靠系统本身就能对车辆进行连续的三维定位和三维定向。卫星导…...

Netty简介

Netty Netty初体验基础概念Reactor模型传统的阻塞IO模型基础Reactor模型多线程Reactor模型 为什么要使用Netty? (NIO的框架,用于解决高并发出现的问题) *BIO:同步且阻塞的IO NIO:同步且非阻塞的IO(不是说线程&#x…...

基于TCP/IP对等模型对计算机网络知识点的整合

目录 前言 应用层 Telnet SSH FTP/TFTP SNMP:简单的网络管理协议 HTTP:超文本传输协议 SMTP:电子邮件传输协议 DNS:域名解析协议 DHCP:动态主机配置协议 NTP:网络时钟协议 传输层 TCP UDP 端…...

【SQL应知应会】表分区(一)• Oracle版

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习,有基础也有进阶,有MySQL也有Oracle 分区表 • Oracle版 前言一、分区表1.什么是表分区…...

PostgreSQL 常用空间处理函数

1.OGC标准函数 管理函数: 添加几何字段 AddGeometryColumn(, , , , , ) 删除几何字段 DropGeometryColumn(, , ) 检查数据库几何字段并在geometry_columns中归档 Probe_Geometry_Columns() 给几何对象设置空间参考(在通过一个范围做空间查询时常用&…...

ubuntu初始化/修改root密码

1.登录ubuntu后,使用sudo passwd root命令,进行root密码的初始化/修改,注:这里需要保证两次输入的密码都是同一个,才可成功 ubuntugt-ubuntu22-04-cmd-v1-0-32gb-100m:~/ocr$ sudo passwd root New password: Retype…...

【Linux后端服务器开发】select多路转接IO服务器

目录 一、高级IO 二、fcntl 三、select函数接口 四、select实现多路转接IO服务器 一、高级IO 在介绍五种IO模型之前,我们先讲解一个钓鱼例子。 有一条大河,河里有很多鱼,分布均匀。张三是一个钓鱼新手,他钓鱼的时候很紧张&a…...

支持向量机(iris)

代码: import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn import svm import numpy as np# 定义每一列的属性 colnames [sepal-length, sepal-width, petal-length, petal-width, class] # 读取数据 iris pd.read_csv(data\\i…...

24考研数据结构-第二章:线性表

目录 第二章:线性表2.1线性表的定义(逻辑结构)2.2 线性表的基本操作(运算)2.3 线性表的物理/存储结构(确定了才确定数据结构)2.3.1 顺序表的定义2.3.1.1 静态分配2.3.1.2 动态分配2.3.1.3 mallo…...

Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述动态 sql 的执行原理不?

OGNL表达式 OGNL,全称为Object-Graph Navigation Language,它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,它旨在提供一个更高的更抽象的层次来对Java对象图进行导航。 OGNL表达式的基本单位是"导航链"&a…...

250_C++_typedef std::function<int(std::vector<int> vtBits)> fnChkSstStt

假设我们需要定义一个函数类型来表示一个能够计算整数向量中所有元素之和的函数。 首先,我们定义一个函数,它的参数是一个 std::vector 类型的整数向量,返回值是 int 类型,表示所有元素之和: int sumVectorElements(std::vector<int> vt) {int sum = 0;for (int n…...

无涯教程-jQuery - Transfer方法函数

Transfer 效果可以与effect()方法一起使用。这会将元素的轮廓转移到另一个元素。尝试可视化两个元素之间的交互时非常有用。 Transfer - 语法 selector.effect( "transfer", {arguments}, speed ); 这是所有参数的描述- className - 传输元素将收到的可选类名。…...

openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符

文章目录 openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符24.1 LIKE24.2 SIMILAR TO24.3 POSIX正则表达式 openGauss学习笔记-24 openGauss 简单数据管理-模式匹配操作符 数据库提供了三种独立的实现模式匹配的方法&#xff1a;SQL LIKE操作符、SIMILAR TO操作符…...

JAVASE---数据类型与变量

1. 字面常量 常量即程序运行期间&#xff0c;固定不变的量称为常量&#xff0c;比如&#xff1a;一个礼拜七天&#xff0c;一年12个月等。 public class Demo{ public static void main(String[] args){ System.Out.println("hello world!"); System.Out.println(…...

IDEA Groovy 脚本一键生成实体类<mybatisplus>

配置数据库&#xff08;mysql&#xff09; 一键生成&#xff08;右键点击table&#xff09; 配置自己的groovy脚本 import com.intellij.database.model.DasTable import com.intellij.database.util.Case import com.intellij.database.util.DasUtil import com.intellij.data…...

无涯教程-jQuery - Puff方法函数

吹气效果可以与show/hide/toggle一起使用。通过按比例放大元素并同时隐藏它&#xff0c;可以形成粉扑效果。 Puff - 语法 selector.hide|show|toggle( "puff", {arguments}, speed ); 这是所有参数的描述- model - 效果的模式。可以是"显…...

什么叫前后端分离?为什么需要前后端问题?解决了什么问题?

单体架构出现的问题 引出&#xff1a;来看一个单体项目架构的结构 通过上述可以看到单体架构主要存在以下几点问题&#xff1a; 开发人员同时负责前端和后端代码开发&#xff0c;分工不明确开发效率低前后端代码混合在一个工程中&#xff0c;不便于管理对开发人员要求高(既会前…...

Vector<T> 动态数组(随机访问迭代器)(答案)

答案如下 //------下面的代码是用来测试你的代码有没有问题的辅助代码,你无需关注------ #include <algorithm> #include <cstdlib> #include <iostream> #include <vector> #include <utility> using namespace std; struct Record { Record…...

Istio 故障注入与重试的实验

故障注入 Istio流量治理有故障注入的功能&#xff0c;在接收到用户请求程序的流量时&#xff0c;注入故障现象&#xff0c;例如注入HTTP请求错误&#xff0c;当有流量进入Sidecar时&#xff0c;直接返回一个500的错误请求代码。 通过故障注入可以用来测试整个应用程序的故障恢…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...