关于Java内存区域的理解和记录

news/2024/11/16 5:32:47/文章来源:https://www.cnblogs.com/ccsu-kid/p/18297938

近期做项目遇到了FullGC的问题,干脆总结一下Java内存区域分布和垃圾回收是咋回事。

Java内存区域按照线程隔离状态直接分成三大块空间:

线程私有:

程序计数器

是一块较小的内存空间,可以看做当前线程所执行的字节码的行号指示器。在虚拟机概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能都需要依赖这个计数器来完成。

由于 JVM 的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令。因此未来线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,故程序计数器是线程私有的。

如果线程正在执行的是一个 Java 方法,这个计数器记录的则是正在执行的虚拟机字节码指令的地址;如果正在执行的是 Native 方法,这个计数器则为空(undefined)。

此内存区域是唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域。

虚拟机栈

和程序计数器一样,虚拟机栈也是线程私有的,且其生命周期与线程相同。

在栈中,每执行一个方法前都会创建一个栈帧,来储存局部变量表、操作数栈、动态链接以及方法出口等信息。每个方法从调用到完成,就对应着栈中一个栈帧的压栈到弹出的过程。

同时一个方法对应的栈帧中局部变量表所需内存空间早已在编译期间就分配完成,当进入一个方法,虚拟机栈对应压入一个栈帧,次栈帧局部变量表空间大小完全确定。

在 Java 虚拟机规范中,对此区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将会抛出 Stack OverflowError 异常;如果虚拟机栈可以动态扩展时无法申请到足够的内存,就会抛出 OutOfMemoryError 异常。

本地方法栈

与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的。

但在我们最常用的 HotSpot 虚拟机中,本地方法栈与 Java 虚拟机栈合二为一。

 

 

线程共享:

Java 堆是一块线程共享的内存区域,它在虚拟机启动时分配创建,它是 JVM 内存里最大的一块内存,但是它的目的只有一个:存放对象实例。

但是随着 JIT 编译器的发展和逃逸分析技术逐渐成熟,栈上分配,标量替换优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上也就变得不那么绝对了。

方法区

又被称非堆(Non-Heap),JVM 虚拟机规范中把方法区描述为堆的一个逻辑部分,它与 Java 堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

但这部分区域又比较特殊,且虚拟机如何实现方法区不受虚拟机规范约束。比如 HotSpot 中,JDK 1.7 之前方法区为永久代,其垃圾回收受 Java 堆 GC 分代收集算法管理,1.7 将 String 常量池移入堆中,1.8 中永久代被完全移除,将类加载信息放入一个线程共享的元空间内。

直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是 JVM 虚拟机规范中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致 OutOfMemoryError 出现。

如 NIO 使用 Native 函数库直接分配堆外内存,然后通过一个 DirectByteBuffer 对象作为这块内存的引用,可以大幅度减轻堆的负担,提高虚拟机性能。

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目前端

目录vue组件基础页面组件组件与链接关联按键绑定网址获取当前网页地址bootstrap常用★实现地图以及地图刷新游戏基类游戏对象地图变量函数null墙★PK页面 vue组件 基础组件名两个大写字母 template,script,style(带上scoped,给该css加上随机字符串,不影响到其他组件) 使用…

Vue3中组件使用ref时获取组件类型推导

本文由 ChatMoney团队出品 我们在使用Vue3+ts开发时,常常会用到一些第三方组件库,比如Element-Plus UI、Navie UI等,这些UI框架中有些组件常常会暴露一些方法给我们便捷的去实现各种复杂的交互,我们经常会像下面这样去给组件定义一个ref去获取组件的实例: <template>…

火山引擎数智平台赋能火花思维,A/B测试加速创新

在数字化浪潮下,火花思维凭借其对数据驱动的理解与实践,搭上了业务快速增长的快车。这一效果的背后,离不开火花思维与火山引擎数智平台的深度合作。通过引入火山引擎的DataFinder和DataTester等产品,火花思维实现了数据问题的快速定位与数据资产的高效利用。更多技术交流、…

node中npm yarn pnpm孰优孰劣???

npm npm2 node版本为4,npm版本就会将为2.x,此时我们执行下那 npm install express分析下node_modules的目录结构。我们会发现, express 包和它的依赖都会被下载下来,展开展开 express,它也有 node_modules:再展开几层,每个依赖都有自己的 node_modules:也就是说 npm2 的…

从0开始搭建博客

1. 概述 本篇博客,我教大家从0开始搭建一个 bolo博客,bolo 博客 和 solo 博客的区别是皮肤更加多,并且可以帐号密码登录。 本篇博客主要的内容如下:linux 安装 docker,设置docker镜像加速 docker 安装 nginx docker 的一些常用的命令 docker 安装 mysql 数据库 docker 安装…

OI 之后的故事 ~After Story~

回归综合 NOI 2023 后,理所当然是回归文化课的学习。 一开始,我惊讶地发现凭借学 OI 期间打下的数学基础及平时阅读英文题面积累的词汇量,我的数学和英语似乎还不错。 最头痛的无疑是语文和物理了。前者属于是玄学,你想到的点答案不一定有;对于后者,计算大题做一道错一道…

CF1936D. Bitwise Paradox-位运算、分治、线段树

link:https://codeforces.com/contest/1936/problem/D 题意:给两个长度为 \(n\) 的序列 \(a\) 和 \(b\),对一个区间 \([l,r]\),称 \([l,r]\) 是好的,若:\((b_l|\dots|b_r)\geq v\)。一个区间的 美丽值 定义为区间内 \(a\) 的最大值。现在有 \(q\) 个操作:1、\(b_i\to x\…

去哪儿故障定位

https://mp.weixin.qq.com/s/9f9PUUy8c-GCJLa0deIvuA

Cilium DSR 特性(转载)

Cilium DSR 特性Cilium DSR(转载) 一、环境信息主机 IPubuntu 10.0.0.234软件 版本docker 26.1.4helm v3.15.0-rc.2kind 0.18.0kubernetes 1.23.4ubuntu os Ubuntu 22.04.6 LTSkernel 5.15.0-106 内核升级文档使用 5.11.5 内核版本的 20.04 版本,发起 curl 请求无法代理到 p…

上传恶意代码服务器和数据库的操作

在通过访问端对服务器上传一句话木马的时候,我们需要对服务器进行部分操作: 1.打开服务器远程目录权限: (1)在windows服务器上,将文件夹的只读方式去掉; (2)在linux服务器上,将文件夹的权限改为pwd 2.开启数据库secure_file_priv权限 (1)我这里使用的是mysql5.7.2…

Zabbix 5.0 LTS URL 健康监测

更多细节详情看【zabbix官方文档】 需求 Zabbix 的URL健康监测功能允许你检测 Web 地址是否可用、正常工作以及响应速度。这对于监控网站的可用性和性能非常有用。例如,你可以监控公司网站、API 端点或其他关键服务的 URL。【官方表述 Web monitoring items】【官方表述 Trigg…

idea 修改 git 提交用户名

本项目 修改配置文件 修改当前项目目录下的 config 文件添加以下数据[user]name = **email = **@gmail.com全局修改 git config --global user.name gitlab注册用户名 git config --global user.email gitlab注册邮箱