您现在的位置是:首页 > 正文

JVM内存布局

2024-01-30 20:29:22阅读 0

目录

内存布局

Heap(堆)

Metaspace(元空间)

JVM Stack(虚拟机栈)

Native Method Stack(本地方法栈)

Program Counter Register(程序计数寄存器)

内存布局

JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM高效稳定的运行。不同的JVM对于内存的划分方式和管理机制存在着部分差异。

JVM内存布局

从线程共享的角度来看,堆和元空间是所有线程共享的,而虚拟机栈、本地方法栈、程序计数器是线程内部私有的。

Java的线程与内存


Heap(堆)

Heap是OOM故障的最主要发源地,它存储着几乎所有的实例对象,堆由垃圾收集器自动回收,堆由各个子线程共享使用。

堆分成两大块:新生代和老年代。

对象产生之初在新生代,步入暮年时进入老年代,但老年代也接纳在新生代无法容纳的超大对象。

新生代分成三部分:一个Eden区,两个Survivor区。

绝大部分对象在Eden区生成,当Eden区满了的时候,会触发Young Garbage Collection,即YGC。没有被引用的对象直接回收,依然存活的对象被移送到Survivor区。

Survivor区分为S0和S1两块内存空间,每次YGC时,它们将存活的对象复制到未使用的那块空间,然后将当前正在使用的空间完全清除,交换两块空间的使用状态。另外每个对象都有一个计数器,记录了存活对象的年龄,当达到一个阈值的时候直接移至老年代,这个阈值默认是15,通过参数-XX:MaxTenuringThreshold控制。

如果YGC要移送的对象大于Survivor区容量的上限,则直接移至老年代。如果老年代也无法放下,则会触发Full Garbage Collection,即FGC。如果依然无法放下,则抛出OOM。

通过设置参数-XX:+HeapDumpOnOutOfMemoryError,使JVM在遇到OOM异常时能够输入堆内信息,以便分析问题原因。


Metaspace(元空间)

在JDK8中,使用元空间代替永久代。

区别于永久代,元空间在本地内存中分配,永久代中的所有内容中字符串常量移至堆内存,其他内容包括类元信息、字段、静态属性、方法、常量等都移至元空间内。


JVM Stack(虚拟机栈)

栈是一个先进后出的数据结构。

JVM中的虚拟机栈是描述Java方法执行的内存区域,它是线程私有的。

栈中的数据都是以栈帧的格式存在,每个方法执行的同时都会创建一个栈帧,方法从开始调用到执行完成的过程,就是栈帧从入栈到出栈的过程。

在活动线程中,只有位于栈顶的帧才是有效的,称为当前栈帧。正在执行的方法称为当前方法,方法执行完会跳转到另一个栈帧上,栈帧是方法运行的基本结构。

栈帧中又包括局部变量表、操作栈、动态连接、方法返回地址等。

(1) 局部变量表:是存放方法参数和局部变量(基本数据类型与引用类型)的区域。相对于类属性变量的准备阶段和初始化阶段来说,局部变量没有准备阶段,必须显示初始化。

(2) 操作栈:是一个初始状态为空的桶式结构栈。在方法执行过程中,会有各种指令往栈中写入和提取信息。

(3) 动态连接:每个栈帧中包含一个在常量池中对当前方法的引用,目的是支持方法调用过程的动态连接。

(4) 方法返回地址:方法执行时有两种退出情况:第一,正常退出;第二,异常退出。无论何种退出情况,都将返回至方法当前被调用的位置,相当于弹出当前栈帧。

StackOverflowError表示请求的栈溢出,导致内存耗尽,通常出现在递归方法中。


Native Method Stack(本地方法栈)

本地方法栈在JVM内存布局中,也是线程对象私有的,但是虚拟机栈“主内”,而本地方法栈“主外”,这里“内外”是针对JVM。

本地方法栈为Native方法服务,线程调用本地方法时,会进入一个不再受JVM约束的世界。

本地方法可以通过JNI(Java Native Interface)来访问虚拟机运行时的数据区,甚至可以调用寄存器,具有和JVM相同的能力和权限。

当大量本地方法出现时,势必会削弱JVM对系统的控制力,因为它的出错信息都比较黑盒,对于内存不足的情况,本地方法栈还是会抛出native heap OutOfMemory。


Program Counter Register(程序计数寄存器)

每个线程在创建后,都会产生自己的程序计数器和栈帧,程序计数器用来存放执行指令的偏移量和行号指示器等,线程执行或恢复都要依赖程序计数器。程序计数器在各个线程之间互不影响,此区域也不会发生内存溢出异常。

网站文章

  • css固定定位

    css固定定位

    主要使用场景:可以在浏览器页面滚动元素时元素的位置不会改变。1、以浏览器的可视窗口作为参考点移动元素。4、不占有固定位置,浮起来了。3、不随滚动条的滚动而变化。2、和父元素没有关系。

    2024-01-30 20:28:51
  • 使用jQuery的ajax上传文件报错:Uncaught TypeError: Illegal invocation

    使用ajax上传文件,代码如下:$('#video-upload-btn').on('change', function(){ var file = this.files[0]; var data =...

    2024-01-30 20:28:44
  • Java代码审计之RCE(远程命令执行)

    Java代码审计之RCE(远程命令执行)

    Java代码审计系列课程(点我哦)漏洞原理:RCE漏洞,可让攻击者直接向后台服务器远程注入操做系统命令或者代码,从而控制后台系统。出现此类漏洞通常由于应用系统从设计上须要给用户提供指定的远程命令操做的...

    2024-01-30 20:28:37
  • Android面试题集-常见几个面试题详解

    Android面试题集-常见几个面试题详解

    跳槽,这在 IT 互联网圈是非常普遍的,也是让自己升职加薪,走上人生巅峰的重要方式。那么作为一个普通的Android程序猿,我们如何才能斩获大厂offer 呢? 疫情向好、面试在即,还在迷茫踌躇中的后...

    2024-01-30 20:28:06
  • 使用EasyExcel实现上传解析与导出下载

    使用EasyExcel实现上传解析与导出下载

    使用指南:https://www.yuque.com/easyexcel/doc/easyexcel 环境:jdk1.8、SpringBoot 2.2.2 准备工作: pom.xml 添加依赖jar包...

    2024-01-30 20:27:57
  • AF_INET 和PF_INET区别;AF_LOCAL PF_LOCAL 区别.

    从字面理解: AF_INET = Address Format, Internet = IP Addresses PF_INET = Packet Format, Internet = IP, TCP/IP or UDP 从linux的定义来看,两者无区别。 /* Supported address families. */#define AF_UNSPEC 0#define AF_UNI...

    2024-01-30 20:27:55
  • springboot和vue前后端分离部署微信公众号

    网上已经有很多vue打包后放到resources目录的解决方案,也有vue前台微信插件然后请求后台方案,我就不Ctrl+C加Ctrl+V了。说说我的分离部署的解决方案:nginx反响代理后台路径,后端验证通过后跳转前端路径通过response.sendRedirect("前台的路径"),如/api,原来http://localhost:8080/user/login,变成http://xx...

    2024-01-30 20:27:49
  • 负数在计算机中怎样存储

    负数在计算机中怎样存储

    一、什么是原码、反码、补码?分为:正数 和负数(包括正浮点数,和负浮点数)规定最高位位符号位正数为0,负数为1(原因下文解释)原码:10进制转换成2进制是原码,只不过正数的原码是本身符号位为0,负数的原码符号位为1(以下篇幅均以单字节为例:10进制1的原码是0000 0001,10进制-1的原码是1000 0001)。反码: 正数的反码是本身,负数的反码是负数的原码0变为1,1变为0 &...

    2024-01-30 20:27:16
  • php create_function()产生的漏洞

    create_function(‘参数’,’函数体’):官方example:

    2024-01-30 20:27:10
  • leetcode解题思路分析(一百二十三)1018 - 1024 题

    代码】leetcode解题思路分析(一百二十三)1018-1024题。

    2024-01-30 20:26:36