JVM的内存区域划分

一文带你搞懂JVM虚拟机的内存区域划分 阅读详情

 JVM的内存区域划分

  学过C语言的朋友都知道C编译器在划分内存区域的时候经常将管理的区域划分为数据段和代码段,数据段包括堆、栈以及静态数据区。那么在Java语言当中,内存又是如何划分的呢?

  由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程:

                                       

  如上图所示,首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。在整个程序执行过程中,JVM会用一段空间来存储程序执行期间需要用到的数据和相关信息,这段空间一般被称作为Runtime Data Area(运行时数据区),也就是我们常说的JVM内存。因此,在Java中我们常常说到的内存管理就是针对这段空间进行管理(如何分配和回收内存空间)。

  在知道了JVM内存是什么东西之后,下面我们就来讨论一下这段空间具体是如何划分区域的,是不是也像C语言中一样也存在栈和堆呢?

一.运行时数据区包括哪几部分?

  根据《Java虚拟机规范》的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register)、Java栈(VM Stack)、本地方法栈(Native Method Stack)、方法区(Method Area)、堆(Heap)。

  如上图所示,JVM中的运行时数据区应该包括这些部分。在JVM规范中虽然规定了程序在执行期间运行时数据区应该包括这几部分,但是至于具体如何实现并没有做出规定,不同的虚拟机厂商可以有不同的实现方式。

二.运行时数据区的每部分到底存储了哪些数据?

  下面我们来了解一下运行时数据区的每部分具体用来存储程序执行过程中的哪些数据。

1.程序计数器

  程序计数器(Program Counter Register),也有称作为PC寄存器。想必学过汇编语言的朋友对程序计数器这个概念并不陌生,在汇编语言中,程序计数器是指CPU中的寄存器,它保存的是程序当前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址),当CPU需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加1或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令。

  虽然JVM中的程序计数器并不像汇编语言中的程序计数器一样是物理概念上的CPU寄存器,但是JVM中的程序计数器的功能跟汇编语言中的程序计数器的功能在逻辑上是等同的,也就是说是用来指示 执行哪条指令的。

  由于在JVM中,多线程是通过线程轮流切换来获得CPU执行时间的,因此,在任一具体时刻,一个CPU的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都需要有自己独立的程序计数器,并且不能互相被干扰,否则就会影响到程序的正常执行次序。因此,可以这么说,程序计数器是每个线程所私有的。

  在JVM规范中规定,如果线程执行的是非native方法,则程序计数器中保存的是当前需要执行的指令的地址;如果线程执行的是native方法,则程序计数器中的值是undefined。

  由于程序计数器中存储的数据所占空间的大小不会随程序的执行而发生改变,因此,对于程序计数器是不会发生内存溢出现象(OutOfMemory)的。

2.Java栈

  Java栈也称作虚拟机栈(Java Vitual Machine Stack),也就是我们常常所说的栈,跟C语言的数据段中的栈类似。事实上,Java栈是Java方法执行的内存模型。为什么这么说呢?下面就来解释一下其中的原因。

  Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向当前方法所属的类的运行时常量池(运行时常量池的概念在方法区部分会谈到)的引用(Reference to runtime constant pool)、方法返回地址(Return Address)和一些额外的附加信息。当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。当方法执行完毕之后,便会将栈帧出栈。因此可知,线程当前执行的方法所对应的栈帧必定位于Java栈的顶部。讲到这里,大家就应该会明白为什么 在 使用 递归方法的时候容易导致栈内存溢出的现象了以及为什么栈区的空间不用程序员去管理了(当然在Java中,程序员基本不用关系到内存分配和释放的事情,因为Java有自己的垃圾回收机制),这部分空间的分配和释放都是由系统自动实施的。对于所有的程序设计语言来说,栈这部分空间对程序员来说是不透明的。下图表示了一个Java栈的模型:

  局部变量表,顾名思义,想必不用解释大家应该明白它的作用了吧。就是用来存储方法中的局部变量(包括在方法中声明的非静态变量以及函数形参)。对于基本数据类型的变量,则直接存储它的值,对于引用类型的变量,则存的是指向对象的引用。局部变量表的大小在编译器就可以确定其大小了,因此在程序执行期间局部变量表的大小是不会改变的。

  操作数栈,想必学过数据结构中的栈的朋友想必对表达式求值问题不会陌生,栈最典型的一个应用就是用来对表达式求值。想想一个线程执行方法的过程中,实际上就是不断执行语句的过程,而归根到底就是进行计算的过程。因此可以这么说,程序中的所有计算过程都是在借助于操作数栈来完成的。

  指向运行时常量池的引用,因为在方法执行的过程中有可能需要用到类中的常量,所以必须要有一个引用指向运行时常量。

  方法返回地址,当一个方法执行完毕之后,要返回之前调用它的地方,因此在栈帧中必须保存一个方法返回地址。

  由于每个线程正在执行的方法可能不同,因此每个线程都会有一个自己的Java栈,互不干扰。

3.本地方法栈

  本地方法栈与Java栈的作用和原理非常相似。区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的。在JVM规范中,并没有对本地方发展的具体实现方法以及数据结构作强制规定,虚拟机可以自由实现它。在HotSopt虚拟机中直接就把本地方法栈和Java栈合二为一。

4.堆

  在C语言中,堆这部分空间是唯一一个程序员可以管理的内存区域。程序员可以通过malloc函数和free函数在堆上申请和释放空间。那么在Java中是怎么样的呢?

  Java中的堆是用来存储对象本身的以及数组(当然,数组引用是存放在Java栈中的)。只不过和C语言中的不同,在Java中,程序员基本不用去关心空间释放的问题,Java的垃圾回收机制会自动进行处理。因此这部分空间也是Java垃圾收集器管理的主要区域。另外,堆是被所有线程共享的,在JVM中只有一个堆。

5.方法区

  方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。

  在Class文件中除了类的字段、方法、接口等描述信息外,还有一项信息是常量池,用来存储编译期间生成的字面量和符号引用。

  在方法区中有一个非常重要的部分就是运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的运行时常量池就被创建出来。当然并非Class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如String的intern方法。

  在JVM规范中,没有强制要求方法区必须实现垃圾回收。很多人习惯将方法区称为“永久代”,是因为HotSpot虚拟机以永久代来实现方法区,从而JVM的垃圾收集器可以像管理堆区一样管理这部分区域,从而不需要专门为这部分设计垃圾回收机制。不过自从JDK7之后,Hotspot虚拟机便将运行时常量池从永久代移除了。

  以上为个人看法和观点,如有不正之处希望谅解并欢迎指正。

  参考资料:

  http://blog.youkuaiyun.com/ns_code/article/details/17565503

  http://www.cnblogs.com/sunada2005/p/3577799.html

  《深入理解Java虚拟机》

  《Java虚拟机规范 SE7》

  转载请标明地址:http://www.cnblogs.com/dolphin0520/p/3613043.html

判断两个多边形是否相交(java实现) 判断两个多边形是否相交 ,当前认为一个点相交也是相交,可针对凹多边形和凸边型等多复杂的多边形进行相交判断,采用java实现,因为网上java实现的比较少,所以这里写下如何实现,适用于碰撞检测,地图等等应用场景 阅读详情

相关推荐

静态与动态LACP链路聚合:原理、配置与排错实战指南

链路聚合技术是提升网络带宽与可靠性的核心方案,通过将多个物理端口逻辑捆绑,实现带宽叠加与链路冗余。其原理基于IEEE 802.3ad标准,通过负载均衡算法将数据流分布到不同物理链路,既避免了数据包乱序,又提升了整体吞吐量。该技术的核心价值在于消除单端口瓶颈、提供毫秒级故障切换,并能简化网络拓扑管理。在企业服务器接入、数据中心互联及虚拟化平台等场景中,链路聚合已成为构建高可用网络的基础。实践中,动态LACP模式通过协议报文协商,能主动检测链路故障并防止配置错误导致的网络环路,相比静态聚合更为可靠。本文将深入解

weixin_31412781的博客 268

JVM的内存区域划分,对象实例化分析

由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程:                                           如上图所示,首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载

每天迈出一小步! 2603

opencv简单小项目

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库,它提供了大量的图像和视频处理功能。要开始一个OpenCV项目,你需要安装OpenCV库,这通常可以通过Python的pip包管理器完成。替换为你要加载的图像的实际路径。这个例子展示了OpenCV项目的基本结构,你可以在此基础上添加更多的图像处理功能。如果你需要更详细的指导或代码示例,请告诉我你的具体需求。

youyouxiong的博客 972

JVM内存分析

JVM实际内存占用超过Xmx的原因,设置Xmx的技巧:https://blog.youkuaiyun.com/begefefsef/article/details/126411842。聊聊jvm的CompressedClassSpace:https://blog.youkuaiyun.com/li123128/article/details/88928392。史上最全的JVM配置参数大全:https://blog.youkuaiyun.com/weixin_41883161/article/details/129557331。

yyc0227的博客 1319

[NVME] CMBLOC-Controller Memory Buffer Location

CMBLOC-Controller Memory Buffer Location

jinyuya的博客 990

公文派2025:免费社区版重大安装更新!

距离上一次更新已经过去了将近一年的时间,今天我们带来了全新的免费2025社区版,该版本也是目前最新的版本,无需授权即可使用所有的功能。

似最初 1963

【JVM】堆内存分析,常见内存溢出,GC日志分析轻重GC,jstack,jcmd,JMX,死锁,jmap,CMS,JVM常见参数

【JVM】堆内存分析,常见内存溢出,GC日志分析轻重GC,jstack,jcmd,JMX,死锁,jmap,CMS,JVM常见参数

qq120631157的博客 4201

PLDM实战解析:传感器与效应器在智能监控系统中的应用

本文深入解析了PLDM(平台级数据模型)中传感器与效应器两大核心组件在智能监控系统中的应用。传感器负责感知硬件状态,分为数值型与状态型,提供精准的“体检报告”;效应器则负责执行控制指令,实现从监控到操作的闭环。文章通过实战案例,阐述了如何利用这些标准化组件构建高效、自动化的智能监控系统,并探讨了平台描述记录与事件机制等关键技术。

k6l7m8n9的博客 874

JVM--内存模型、垃圾回收、常见面试题、JVM调优

2:进入TLAB区:如果TLAB区域足够装下对象则直接进入,如果装不下则根据refill_waste(JVM运行时动态维护的一个变量)会有两种情况:1:请求对象大于refill_waste时将当前TLAB区域剩余的区域用dump object填满然后新开辟一块TLAB区域存放该对象;根可达算法:从根元素(栈里引用的对象、本地方法栈引用的对象、常量池内对象、静态变量引用的对象、.class对象)开始寻找,凡是通过根元素可以搜索到的对象,都不是垃圾。大对象:Eden区分配不下;

u012218309的博客 1171

泰克示波器TDS210改装便携示波器

泰克示波器TDS210改装编写示波器

超级网吧的博客 3080

增程式永磁电机发电系统电压环二自由度控制器设计

本论文主要研究增程式永磁电机发电系统的电压环二自由度控制器设计。该系统采用二自由度控制策略,通过精确调节电压环和电流环,显著提高系统的动态响应性能和稳态稳定性。基于SVPWM(空间矢量脉宽调制)技术,本研究设计的电压环控制器能够在负载突变和外部扰动的情况下,快速恢复并保持电压稳定,从而满足增程式永磁电机发电系统对电压精度和稳定性的高要求。仿真分析表明,所设计的控制器在不同工况下展现出良好的电压稳定性、较短的响应时间和较低的稳态误差,能够有效抑制电压波动并提高系统的鲁棒性。实验结果表明,控制器在维持高效能和高

weixin_44553616的博客 897

JVM内存性能调优思路之:通过GC log、Thread Dump 、Heap Dump分析内存使用说明

JVM内存性能调优思路之:通过GC log、Thread Dump 、Heap Dump分析内存使用说明

hiliang521的博客 1709

解锁RK平台黑科技:DPDK加速与硬件卸载实战

本文探讨了在RK平台上通过DPDK加速与硬件卸载技术构建高性能网络架构的方法。RK平台凭借强大的硬件性能为高并发网络处理提供基础,而DPDK通过用户态驱动、轮询机制等技术绕过内核瓶颈,显著提升数据包处理效率。硬件卸载则将校验和计算等任务交由专用硬件,释放CPU资源。实践案例显示,该方案可使网络吞吐量提升至理论极限,延迟降至5ms以下,CPU利用率降低40%。文章详细介绍了配置步骤、优化方法和常见问题解决方案,并展望了该技术在5G、车联网等新兴领域的应用前景。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 1280

【JVM】JVM执行流程和内存区域划分

`Java` 不想重新编译,而是期望能够直接执行 - 先通过 `javac` 把 `.java` 文件==> `.class` 文件(字节码文件,包含的就是 `Java` 字节码,`Java` 自己搞的一套 `CPU` 指令) - 因为如果生成 `CPU` 直接能执行的指令的话,不同的 `CPU` 支持的指令就不一样,就不能在所有系统上执行 - 这样先把 `java` 代码转成对应的 `java` 字节码文件,然后在某个具体的系统平台上执行,此时通过 `JVM` 把上述的字节码转换成对应的 `CPU` 能

Yeeear的博客 1万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

JVM内存区域划分

JVM全称Java Virtual Machine,也称java虚拟机。那什么是虚拟机呢,相信大家应该多多少少都有听说过。就是。简单粗暴的可以理解为可以在上面进行一些操作的一个计算机,但是这个计算机是虚拟的、不存在。

m0_63039919的博客 1795

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

JVM内存区域划分详解

JVM内存区域分为运行时数据区和直接内存。运行时数据区包括程序计数器、虚拟机栈、本地方法栈(均为线程私有)、堆和元空间(线程共享)。堆分为年轻代(Eden、Survivor区)和老年代,是GC主要区域;元空间存储类元数据。直接内存是堆外内存,用于NIO操作。常见内存异常包括堆溢出(OOM)、栈溢出(StackOverflowError)等。调优参数如-Xms/-Xmx控制堆大小,-Xss设置栈大小。理解JVM内存模型对性能调优和问题排查至关重要。

weixin_43076660的博客 779

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java面试必备:JVM内存区域的划分

Java虚拟机(JVM)是Java程序运行的核心环境,它负责管理程序的内存、执行字节码以及处理垃圾回收等任务。理解JVM的内存区域划分对于编写高效、稳定的Java程序至关重要。本文将详细介绍JVM的内存区域划分,并通过流程图帮助读者更好地理解这些概念。

qq_58299462的博客 935

jvm(一)——内存区域划分

前言:jvm内存划分为多个区域,每个不同的区域分别有着不同的功能和不同的用途,本篇博客旨在说清楚区域的划分、名称、属性以及作用,本篇博客是参考了多篇博客的结果,参考博客会在文章结尾进行说明。 上图中说明了堆中对象的分配来源,对象实例化在堆中,但是其引用可能在方法区(常量实例),或者虚拟机的栈帧中(java方法中的实例化)和本地方法栈中(本地方法对象的实例化),在下面有详细说明。 一.程...

节至 1945

【JVM】谈谈JVM内存区域的划分

对 Java 程序员来说我们不用自己手动管理对象内存的申请与释放,全部交由 Java 虚拟机(JVM)来管理内存的分配与回收。 因此,日常开发中我们不用关心内存分配与回收,减少了很多繁琐的工作,大大提高了开发效率。 也正是因为如此,一旦出内存泄漏和溢出方面的问题,如果不了解 JVM 内部的内存结构、工作机制,那么排查问题将变得异常艰难。 接下来,我们一起学习 JVM 内存区域的划分、作用以及可能产生的问题。 根据 Java 虚拟机规范,Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为几

Geek_ymv的专栏 734

JVM 的内存区域是如何划分的?

和虚拟机栈作用类似,只是服务对象不同。👉 Java 调用“外援”的专用通道。JVM 靠它知道“下一条指令去哪”例如调用 C / C++ 代码。👉 方法调用的“通话记录”符号引用(类、方法、字段)👉 JVM 的“常量词典”每个方法调用都会创建一个。垃圾回收(GC)的主战场。👉 对象的“集中居住区”记录当前线程正在执行的。👉 JVM 的“书签”👉 类的“说明书仓库”字面量(字符串、数字)逻辑上属于堆的一部分。

2201_75642742的博客 982

JVM内存区域划分以及GC原理

JVM 是 Java Virtual Machine 的简称,意为 Java虚拟机。虚拟机是指通过软件模拟的具有完整硬件功能的、运⾏在⼀个完全隔离的环境中的完整计算机系统。常见的虚拟机:JVM、VMwave、Virtual Box。JVM 和其他两个虚拟机的区别:1.VMwave与VirtualBox是通过软件模拟物理CPU的指令集,物理系统中会有很多的寄存器;2.JVM则是通过软件模拟Java字节码的指令集,JVM中只是主要保留了PC寄存器,其他的寄存器都进行了裁剪。

2301_79995226的博客 1375
上一篇: 浅谈Java中的hashcode方法
下一篇: Java异常处理和设计
鹿晗的晗
博客等级 码龄16年 22粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值