JVM初探(一):jvm内存结构[通俗易懂]

JVM初探(一):jvm内存结构[通俗易懂]一、概述我们知道java代码先编译为.class文件,然后再将.class文件交由jvm执行。在程序运行的这一过程中,jvm会将其管理的内存空间划分为不同的区域,这些区域各有各的用途,我们将其分为五

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、概述

我们知道java代码先编译为.class文件,然后再将.class文件交由jvm执行。在程序运行的这一过程中,jvm会将其管理的内存空间划分为不同的区域,这些区域各有各的用途,我们将其分为五类:

  1. 方法区
  2. 虚拟机栈
  3. 本地方法栈
  4. 程序计数器

其中方法区和堆是线程共享的,随jvm启动和停止而创建和销毁;

而虚拟机栈、本地方法栈和程序计数器则是线程私有的,随线程的创建和结束而创建和销毁。

jvm内存体系

二、线程隔离数据区

包括程序计数器,虚拟机栈,本地方法栈三部分,是线程私有的数据区。

1.程序计数器

程序计数器

程序计数器用于记录当前线程执行的字节码指令的地址。

我们知道cup实现多线程操作是根据每个线程分配是时间片来决定处的,每一个时间片cup都只处理抢到那个时间片的线程,因此很可能出现线程1指令执行到一半,结果下一个时间片又去处理另一个线程了。

为了能够在线程切换后依然能恢复到正确的指令位置,每一个线程都需要一个独立的计数器去记录正在执行的字节码指令地址,我们可以简单的理解为一个记录执行到的指令行数的一个指示器。

如果指向的是java方法,计数器记录执行的字节码的地址,如果是非java代码的Native方法,这计数器为空。

计数器是唯一一个没有规定OutOfMemoryError的区域。

2.虚拟机栈

虚拟机栈

虚拟机栈是描述java方法执行的一个内存模型。

每个方法执行的时候会常见一个栈帧,栈帧中会储存局部变量表。操作数栈、动态链接、方法出口信息等。比如方法的局部变量会插入局部遍历表,对局部变量的运算和传递则通过数栈等等。

每个方法从调用到完成就是一个栈帧在虚拟机栈中入栈到出栈的一个过程。我们使用递归时提到的栈就是虚拟机栈。

虚拟机栈规定有两种异常:StackOverflowErrorOutOfMemoryError

我们知道方法调用实际就是栈帧入栈,如果栈的深度超过规定,就会抛出StackOverflowError异常

栈的大小可以规定也可以动态扩展,如果栈扩展大小时申请不到足够的内存,就会抛出OutOfMemoryError异常.

3.本地方法栈

本地方法栈

本地方法栈是描述j非java的方法执行的一个内存模型。

它与虚拟机栈功能一样,但是不同的是本地方法栈用于存放实现方法非java代码的方法。当一个java方法要调用的的时候,会将java栈帧入虚拟机栈,而当非java方法要调用的时候就会入本地方法栈。

实际上两种栈之间往往会互相调用对方的方法,比如java方法A调用了java方法B,java方法B调用了C++方法C,这个C++方法又调用了java方法D,描述一下过程就会是:

A =》虚拟机栈,B =》虚拟机栈,C =》本地方法栈,D =》虚拟机栈

二、线程共享数据区

1.堆

java堆

堆用于存放对象实例、数组和字符串常量池

堆用于存放类的实例对象、数组和字符串常量池、另外,由于实例对象存储于此区域,所以也是垃圾收集器管理的主要区域,故又称GC堆

java对可以是固定大小,也可以是动态大小,如果堆中没有内存分配给新的实例对象的时候,就会抛出OutOfMemoryError异常

1.2字符串常量池

这里稍微提一下字符串常量池,正由于字符串常量池的存在,当创建字符串常量时,首先检查字符串常量池是否存在该字符串,存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中

这也是为什么字符串明明是对象却可以直接使用 == 比较,因为同样的字符指向的都是常量池里同一个字符串对象。

1.3 垃圾回收策略

另外值得一提的是,堆往往和垃圾回收问题一起出现,所以这里也简单的介绍一下内存分配和回收的策略:

由于jvm内存回收机制采用了分代收集算法,所以java堆中还分为新生代和老年代,新生代中又分为占大部分控件的eden区域和占较小空间的survivorSpace0survivorSpace1

根据分代收集算法,对在给新实例进行内存分配时一般遵循以下原则:

  • 对象优先分配给eden区域。当eden区域没有足够弓箭时,发起一次GC。当垃圾回收时,根据复制算法:

    eden和一个survivorSpace中还存活的对象会复制到另一个survivorSpace中,然后清理原先的空间

  • 需要大量连续内存空间的大对象直接进入老年代。比如巨长的数组或者字符串,还有非常高的树之类的。

  • 长期存活的对象会进入老年代。对象在新生代活过一定次数GC后会移入老年代。

当然,不同的垃圾收集器和不同的垃圾收集算法适应不同的程序运行情况,实际的内存回收机制要复杂的多,这里以后会在新随笔里另外再展开,这里就不再赘述了。

2.方法区

方法区主要用来存放类信息、类的静态变量、常量、运行时常量池等

方法区和堆功能类似,主要用与存放类信息,常量和即时编译器编译后的代码等数据。

2.2永久代

很多文章提到方法区的时候都会涉及到这个“永久代”这个词。实际上,方法区是jvm的一个规范,永久代是这种规范的另一种实现,类似的还有元空间,这也是方法区的一种实现。

jvm虚拟机分为很多种,比如HotSpot ,JRockit(Oracle)、J9(IBM)等等,但是只有HotSpot才有永久代这个说法。硬要说的话,方法区可以理解为一个接口,永久区是这个接口的实现类。

2.3 运行时常量池

运行时常量池

类似的问题还有运行时常量池。运行时常量池是方法区的一部分,用于存储各种编译时以及运行时产生的新常量,类加载以后的数据就存放于此,还有字符串手动入池方法intern()

这里的 “运行时常量池”同上文提到的方法区和永久代的关系一样,也是jvm的规范而不是实现,运行时常量必然会有一个专门的储存空间,但是放在哪就得看虚拟机各自的实现了。

不过这里要额外理解一下字符串常量池:

常量池分为两块,一块是堆中的字符串常量池,一块是方法区中的常量池。实际上JDK8之前字符串常量池也在方法区中的常量池里边,而在JDK8之后被单独分离出来放到了堆里

字符串常量池在JDK8被分离

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/170797.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 高光谱图像分类综述_高光谱图像样本进行扩增

    高光谱图像分类综述_高光谱图像样本进行扩增PCA-PrincipleComponentAnalysis主成分分析ICA-IndependentComponentAnalysis独立成分分析NWFE-Nonparametric

  • mysql导入excel表异常_mysql导入excel表格数据时出错的解决

    mysql导入excel表异常_mysql导入excel表格数据时出错的解决NavicatforMySQL导入数据时报错1:导入的是Excel2007表格格式的数据。2:报错以后数据加进去了。(选择了错误继续执行)3:这个错误对我的数据有影响吗?4:造成这个错误的原因是什么5:这个是日志文件[2012-07-1113:57:48][Msg]Importstart[2012-07-1113:57:48][Msg]Importtype-Excel20…

  • Centos7安装Python3与pip3[通俗易懂]

    Centos7安装Python3与pip3[通俗易懂]1.下载Python3官网地址:DownloadPython|Python.org下载tgz包就可以了。其实下面的2个包其一都可以使用Version OperatingSystem Description MD5Sum FileSize GPG Gzippedsourcetarball Sourcerelease 1440acb71471e2394befdb30b1a958d1 25800844 SIG XZ

  • 数据挖掘之时间序列分析[通俗易懂]

    数据挖掘之时间序列分析[通俗易懂]按时间顺序排列的一组随机变量X1,X2,…,Xt表示一个随机事件的时间序列。时间序列分析的目的是给定一个已被观测了的时间序列,预测该序列的未来值。表1常用的时间序列模型 模型名称 描述 平滑法 常用于趋势分析和预测,利用修匀技术,削弱短期随机波动对序列的影响,使序列平滑化。 根据所用平滑技术的不同,可分为移动平均法和指数平滑法。 趋势拟合法…

  • RCNN和SPPnet

    RCNN和SPPnetRCNN的提出首次利用了CNN来提取图片特征,大大提高了检测精度。整体思路:输入一张图片,selectivesearch方法提取2000个proposalregion,由于CNN输入图片的大小是固定的,所以需要把proposalregion变成同样的大小(比如227×227),然后通过五层卷积层和两个全连接层,然后用SVM进行分类因为我们后面还要继续用这2000个候选框图片,继续…

  • TortoiseSVN新人使用指南[通俗易懂]

    TortoiseSVN新人使用指南[通俗易懂]这篇文章源于6月份给公司新人作的关于SVN使用的培训,转眼已经过了几个月的时间,丢了也怪可惜的,于是整理出来希望能够帮助后来人快速入门。安装说明使用说明检出项目导入项目提交更新查看日志版本回滚版本控制总结安装说明开发人员强烈建议使用IDE中的SVN插件更加智能与人性化。首先安装SVN客户端,windows一般选择乌龟客户端https://tortoisesvn.net/d

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号