JVM 内存区域

一、JVM 简介

【概述】

JVM是Java虚拟机(Java Virtual Machine)的简称,是一种用于计算设备的规范,是一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。我们学习使用的基本都是HotSpot虚拟机。

【优点】

优点

说明

实现跨平台运行

让底层代码和运行环境分离开,编写好一份代码后,不用再次修改内容,只用通过安装不同的JVM环境自动进行转换即可运行,在各种系统中无缝连接。

自动内存管理

专门设计了垃圾回收机制,来自动进行内存的管理,极大的优化了操作。

数组下标越界检查

提供了数组下标越界的自动检查机制,在检测到越界后,会在运行时自动抛出ArrayIndexOutOfBoundsException

多态

通过相同接口,不同的实例进行实现,完成不同的业务操作

二、JVM 内存区域

(一) 简图

(二) 各区域详解

1. Java虚拟机栈

【概述】

Java虚拟机栈绝对算的上是 JVM 运行时数据区域的一个核心,除了一些Native方法调用是通过本地方法栈实现的(下面会提到),其他所有的Java方法调用都是通过虚拟机栈来实现的。

【特点】

  1. 线程私有,生命周期和线程相同,随着线程的创建而创建,随着线程的死亡而死亡,不存在垃圾回收问题;
  2. Java方法调用的数据需要通过虚拟机栈栈进行传递;
  3. 每一次方法调用都会有一个对应的栈帧被压入栈中(先进后出);
  4. 每一个方法调用结束后,都会有一个栈帧被弹出(后进先出);
  5. 栈由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法返回地址。
  6. 每个方法执行的同时会创建一个栈帧,一个方法就对应一个栈帧

Java方法有两种返回函数的方式,不管使用哪种方式,都会导致栈帧被弹出。

  1. 正常的函数返回,使用return指令;
  2. 抛出异常(没有try catch)。

【栈溢出】

  1. StackOverFlowError 若栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前Java虚拟机栈的最大深度的时候,就抛出该错误。
  2. OutOfMemoryError 如果栈的内存大小可以动态扩展, 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出该异常。

【栈帧】

这里参考《深入理解 Java 虚拟机》这本书,只是做了简单的总结,具体的细节想了解的可以去读。

名称

说明

局部变量表

用于存放方法参数和方法内部定义的局部变量,在 Java 程序被编译为 Class 文件时确定最大容量。

操作数栈

主要作为方法调用的中转站使用,用于存放方法执行过程中产生的中间计算结果。另外,计算过程中产生的临时变量也会放在操作数栈中。

动态链接

指向运行时常量池的方法引用

方法返回地址

方法正常退出或者异常退出的定义

在Java源文件被编译成字节码文件时,所有的变量和方法引用都作为符号引用(Symbilic Reference)保存在Class文件的常量池里。当一个方法要调用其他方法,需要将常量池中指向方法的符号引用转化为其在内存地址中的直接引用。动态链接的作用就是为了将符号引用转换为调用方法的直接引用。

2. 本地方法栈

  • 和虚拟机栈所发挥的作用非常相似,区别是:虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。
  • 在HotSpot虚拟机中和Java虚拟机栈合二为一;
  • 本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息;
  • 方法执行完毕后相应的栈帧也会出栈并释放内存空间,也会出现StackOverFlowErrorOutOfMemoryError两种错误。

3. PC寄存器

【概述】

程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令。

【作用】

  1. 存指向下一条指令的地址,也即将要执行的代码。由执行引擎读取下一条指令;
  2. 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
  3. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。

【特点】

  1. 线程私有:若干个线程是交替执行的,在线程与线程之间切换的时候,需要记录每个线程执行到那一步了;
  2. 唯一个在Java虚拟机规范中没有规定任何OutOtMemoryError情况的区域;
  3. 它的生命周期随着线程的创建而创建,随着线程的结束而死亡。

4. 堆

【概述】

Java虚拟机所管理的内存中最大的一块,Java堆是所有线程共享的一块内存区域,在虚拟机启动时创建。

【特点】

  1. 此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存;
  2. Java堆是垃圾收集器管理的主要区域,因此也被称作GC堆;
  3. JDK 1.7 开始已经默认开启逃逸分析,如果某些方法中的对象引用没有被返回或者未被使用,则可以直接在栈上分配内存。
  4. 默认情况下,JVM分配的总内存是电脑内存的

    ,初始化的内存是电脑内存的

【空间分类】

  • 新生代
    • Class诞生和生长的地方,甚至死亡;
    • Eden所有的对象都是在Edennew出来的;
    • SurvivorSurvivor分1区和2区,两者是动态的。
  • 老年代
    • 对象年龄达到阈值后进入老年代:默认情况下,对象在新生代经历了15次GC后;
    • 大对象直接进入老年代:通过以下JVM参数进行设置:-XX:PretenureSizeThreshold=5242880

原因:

  1. 大对象需要连续的内存空间,而新生代为了安放大对象可能需要多次进行GC,增加开销;
  2. 新生代种伊甸园区和幸存者区常采用复制算法,需要经常复制对象到不同的区域,而大对象在复制时开销较大。
    • 动态地根据对象的年龄以及新生代空间使用情况选择对象进入老年代。

HotSpot虚拟机并不一定会严格按照设置的年龄阈值,满足以下条件也能直接进入老年代:

Survivor区中,年龄从 1 到 n 的对象大小之和超过Survivor区的50%时,新生代中年龄大于等于 n 的对象将进入老年代。(这个对象大小总和是按年龄从小到大累加的,并不是同龄对象!)

  • 永久代(元空间)
    • 这个区域用来存放JDK自身携带的Class对象;
    • 存放Interface元数据,主要是Java运行时的一些环境或类信息;
    • 该区域不存在垃圾回收?关闭虚拟机就会释放这个区域的内存。
    • JDK1.8以后,永久代被元空间替代

【大致过程】

对象都会首先在Eden区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入S0或者S1,并且对象的年龄还会加 1(Eden区->Survivor区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为15岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold来设置。

【内存溢出】

  1. java.lang.OutOfMemoryError: GC Overhead Limit Exceeded 当 JVM 花太多时间执行垃圾回收并且只能回收很少的堆空间时,就会发生此错误。
  2. java.lang.OutOfMemoryError: Java heap space假如在创建新的对象时, 堆内存中的空间不足以存放新创建的对象, 就会引发此错误。(和配置的最大堆内存有关,且受制于物理内存大小)

5. 方法区

【概述】

方法区别名叫做非堆(Non-Heap),目的就是要和堆分开,被所有线程共享。所有字段和方法字节码以及一些特殊方法,如构造函数、接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域上。但是实例变量存在堆内存中,和方法区无关。

【特点】

  1. 方法区和堆一样,是各个线程共享的区域;
  2. 方法区在JVM被启动时创建;
  3. 方法区的大小跟堆空间一样,可以选择固定大小或扩展;
  4. 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出溢出错误OutOfMemoryError
  5. 关闭JVM就会释放这个区域的内存。

【JDK1.8变化】

  • JDK1.6:方法区保存在内存结构中,叫做永久代,里面存储了运行时的常量池(包含串池StringTable)、类的信息、类加载器;
  • JDK1.8:方法区做为一个概念,保存在本地内存中,叫做元空间,里面存储了运行时的常量池、类的信息、类加载器,此时串池(StringTable)储存在堆之中。

【方法区和永久代以及元空间的关系】

方法区和永久代以及元空间的关系很像Java中接口和类的关系,类实现了接口,这里的类就可以看作是永久代和元空间,接口可以看作是方法区,也就是说永久代以及元空间是HotSpot虚拟机对虚拟机规范中方法区的两种实现方式。

6. native关键字

【概述】

native用来修饰方法,凡事带了native关键字的方法,说明Java的作用范围达不到了,需要去调C语言的库。

【语法】

  1. 修饰方法的位置必须在返回类型之前;
  2. 不能用abstract修饰,也没有方法体,也没有左右大括号;
  3. 返回值可以是任意类型;

【特点】

  1. 调用带native关键字的方法,该方法会进入本地方法栈;
  2. 本地方法栈会调用本地方法接口(JNI);

JNI作用:

通过JNI,我们就可以通过 Java 程序(代码)调用到操作系统相关的技术实现的库函数,从而与其他技术和系统交互,使用其他技术实现的系统的功能;同时其他技术和系统也可以通过 JNI 提供的相应原生接口开调用 Java 应用系统内部实现的功能。

【存在原因】

Java诞生的时候,CC++横行,要想立足必须调用他们的程序。所以Java专门在JVM的内存区域中开辟了一块标记区域本地方法栈,用来登记native方法,在最终执行的时候,通过本地方法接口(JNI)加载本地方法库中的方法。

【应用场景】

我们在日常编程中看到native修饰的方法,只需要知道这个方法的作用是什么,在企业级应用中很少见。一般涉及硬件系统相关开发可能会用到,比如Java程序驱动打印机。

7. 执行引擎


参考:

[1] 周志明. 深入理解 Java 虚拟机(第3版).

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

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

相关文章

学习node.js 二 path模块,os模块,process

目录 path模块 1. path.basename() 2. path.dirname 3. path.extname 4. path.join 5. path.resolve 6. path.parse path.format OS模块 1. 获取操作系统的一些信息 (1)os.platform() (2)os.release (3)os.ho…

2024年玩转音乐,不只是剪辑!这4款软件让创意跳跃在每个音符间

现在这年头,音乐不光是听个乐呵,还能暖暖心。要是想自己捣鼓捣鼓这音乐,或者给日常生活加个调调,有个好的音乐剪辑软件就特别重要。今天,我就来晒晒我收藏的那些音乐剪辑软件,这些软件不光是剪剪切切的工具…

分布式缓存———数据一致性问题

分布式基础理论 CAP理论 与 BASE理论-CSDN博客 分布式系统会的三座大山:NPC。 N:Network Delay,网络延迟P:Process Pause,进程暂停(GC)C:Clock Drift,时钟漂移 在当前…

机器学习第十一章——计算学习理论

一、基础知识 计算学习理论(computational learning theory)研究的是关于通过“计算”来进行“学习”的理论,即关于机器学习的理论基础,其目的是分析学习任务的困难本质,为学习算法提供理论保证,并根据分析结果指导算法设计。 给…

Verilog刷题笔记53

题目: Fsm serialdata See also: Serial receiver Now that you have a finite state machine that can identify when bytes are correctly received in a serial bitstream, add a datapath that will output the correctly-received data byte. out_byte needs …

如果忘记了 Apple ID 密码,如何重设

“我忘记了我的 Apple ID 密码,如何恢复我的帐户?”为了方便用户,Apple 允许每个人使用唯一的 Apple ID 和密码激活设备并访问所有 Apple 服务。然而,实际上,手动选择某项并忘记它似乎很容易。例如,许多 Ap…

基于web框架的协同过滤的美食推荐系统【数据爬虫、管理系统、数据可更新、样式可调整】

文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍研究背景研究的目的与意义协同过滤算法基于用户的协同过滤算法定义基于物品的协同过滤算法的定义 数据库设计db_food(美食信息表)db_collect(美食…

eclipse打开失败 java was started but returned exit code=13

报错详细信息如下 原因:eclipse版本和jdk版本不一致。系统之前jdk是1.6,然后安装1.8之后默认修改了环境变量。导致eclipse启动失败 解决方案:修改eclipse目录下的eclipse.ini文件增加一下内容。文档说明:eclipse.ini - Eclipsepe…

还在用Hexo吗?来试试Gatsby搭建一个网站吧!

本文首发于个人博客网站:http://www.blog.lekshome.top/2024/08/20/shi-yong-gatsby-da-jian-ge-ren-wang-zhan/由于CSDN并不是本人主要的内容输出平台,所以大多数博客直接由md文档导入且缺少审查和维护,如果存在图片或其他格式错误可以前往上…

Halcon灰度图像的形态学运算

Halcon灰度图像的形态学运算 本文介绍的算子的输入类型是灰度的Image图像。 1. 灰度图像与区域的区别 基于区域的形态学运算与基于灰度图像的形态学运算的根本区别在于,二者输入的对象不同。前者输入的是一些区域,并且这些区域是经过闽值处理的二值图…

一文搞懂大模型在多GPU环境的分布式训练!

随着大模型时代的到来,模型参数量、训练数据量、计算量等各方面急剧增长。大模型训练面临新的挑战: 显存挑战:例如,175B的GPT-3模型需要175B*4bytes即700GB模型参数空间,而常见的GPU显存如A100是80G显存,这…

visual studio使用技巧:快速生成Json、XML对应类

visual studio快速生成Json、XML对应类 在项目中经常用到json或者xml作为配置文件,进行序列化和反序列化就需要有对应的类,重新写一遍类就比较麻烦,这里就讲一下通过visual studio快速生成json或者xml对应类型的方法。 自动生成Json类 复制…

图像数据处理17

四、形态学图像处理 4.3 开运算与闭运算 4.3.1开运算与闭运算的定义: 开运算:先腐蚀,再膨胀 闭运算:先膨胀,再腐蚀 记忆方法:膨胀(胀开)所以开运算最后对应的结果是膨胀&#x…

c++进阶——继承的定义,复杂的菱形继承及菱形虚拟继承

目录 前言: 1.继承的概念及定义 1.1继承的概念 1.2 继承定义 1.2.2继承关系和访问限定符 1.2.3继承基类成员访问方式的变化 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 5.继承与友元 6. 继承与静态成员 7.复杂的菱形继承及菱…

springsecurity 登录认证一(ajax)

一、准备工作 1.1 导入依赖 因springboot 3.0 以上版本只能支持java17 顾使用2.5.0 版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.0</version><…

网络工程3(子网通信,为什么要使用mac和ip)

文章目录 一. 子网如何通讯1. 子网内部通信2. 子网外部通信 二. 交换机和路由器的连接三. 为什么不只使用mac地址或ip地址进行网络通信1. 首先要明确的是&#xff0c;不管是只用mac或只用ip通信 四. 子网设备如何获得ip五. 不同网段的主机无法直接通信的原因 一. 子网如何通讯 …

音频矩阵主要功能及常规路数配置有哪些

音频矩阵&#xff0c;又称AUDIO矩阵或音频矩阵切换器&#xff0c;是一种用于管理和控制多个音频信号的设备。它具备多种功能&#xff0c;主要可以概括为以下几个方面&#xff1a; 一、主要功能 信号切换&#xff1a; AUDIO128128音频矩阵能够将多个音频源的信号输入到设备中&…

Python实现水果忍者(开源)

一、整体介绍&#xff1a; 1.1 前言&#xff1a; 游戏代码基于Python制作经典游戏案例-水果忍者做出一些改动&#xff0c;优化并增加了一些功能。作为自己Python阶段学习的结束作品&#xff0c;文章最后有源码链接。 1.2 Python主要知识&#xff1a; &#xff08;1&#xf…

怎么选开放式耳机好?精选五款物超所值机型推荐!

耳机已成为我们日常生活中的常见伙伴&#xff0c;无论是听音乐、玩游戏还是看剧&#xff0c;都离不开它。市场上耳机品牌和款式众多&#xff0c;找到一款真正适合自己的并不容易。尤其是长时间佩戴传统入耳式耳机可能会感到耳朵不舒服或闷热。开放式耳机因其非侵入式设计&#…

运维学习————Linux环境下Tomcat的部署

目录 一、环境准备 二、 启动测试 三、访问端口修改 四、部署web项目 1、材料准备 2、部署 2.1、上传war包到webapps目录下 2.2、修改项目配置 2.3、浏览器访问 引申 一、环境准备 tomcat安装包&#xff1a;apache-tomcat-9.0.52 JDK环境&#xff1a; 我使用的y…