首页 > 系统相关 >JVM内存结构

JVM内存结构

时间:2024-03-15 10:34:02浏览次数:18  
标签:Java 虚拟机 线程 内存 JVM 方法 结构

image

我们都知道,我们写的Java程序需要先经过编译,生成了.class文件(字节码文件)。然而,计算机并不能直接解释.class文件里面的内容,这时候就需要一个能加载、解释.class文件并且能按.class文件里的内容进行处理的一个东西--JVM。

JVM,就是Java虚拟机。它是一种规范,有针对不同系统的特定实现(Linux,Windows,macOS)。这样,相同的字节码就能在不同的系统上运行,实现了跨平台运行(Write Once, Run Anywhere)。

JVM的内存结构

JVM的内存结构

上图是JDK1.8的JVM内存结构,可以看出内存结构分为程序计数器、Java虚拟机栈、本地方法栈、堆、元空间,其中程序计数器、Java虚拟机栈、本地方法栈是线程独享的(按线程隔离),其生命周期和所在线程相同,而堆、元空间是线程共享的。

程序计数器

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

注意:程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程的结束而死亡。

Java虚拟机栈

每个Java方法在执行时都会创建一个栈帧(Java方法执行的内存模型)。每一个方法从被调用到执行完成的过程,就是一个栈帧在Java虚拟机栈中入栈到出栈的过程。栈是先进后出的数据结构,也就是说,后被调用的Java方法会先结束。

Java虚拟机栈

上图就是一个Java虚拟机栈的结构,一个Java虚拟机栈是由一个个栈帧组成的,而每个栈帧中都拥有局部变量表、操作数栈、动态链接、方法返回地址。

Java虚拟机栈可能会出现以下两种错误:

StackOverFlowError:若栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前Java虚拟机栈的最大深度的时候,就抛出StackOverFlowError错误。

OutOfMemoryError:如果栈的内存大小可以动态扩展,如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

局部变量表
主要存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。

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

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

动态链接

本地方法栈

本地方法栈与Java虚拟机栈作用相似,它们之间的区别是Java虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、方法返回地址。

堆是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。堆的作用就是存放对象实例,几乎所有对象实例都在这个区域分配内存。

Java堆是垃圾收集器管理的主要区域,因此也叫GC堆(Garbage Collected Heap)。从内存回收的角度(收集器一般采用分代收集算法),Java堆内存可以细分为:新生代和老年代。新生代再细分有:Eden区、Survivor0区、Survivor1区。

堆

根据虚拟机规范,Java堆可以处于物理上的不连续内存中,只要逻辑上是连续即可。其大小可以通过-Xmx和-Xms控制。如果在堆中没有内存完成实例分配,并且堆也无法扩展时会抛出OutOfMemoryError异常。

方法区

方法区结构

虚拟机要使用一个类时,它需要读取并解析.class文件获取相关信息,再将信息存入到方法区。方法区用于存放类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

《Java 虚拟机规范》只是定义了方法区这个概念和它的作用,在不同的虚拟机实现上,方法区的实现是不同的。JDK1.8之前的方法区实现叫永久代,到了JDK1.8,方法区实现叫元空间,它取代了永久代。元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。

方法区、永久代、元空间三者关系

元空间 (MetaSpace)替代永久代(PermGen) 的原因如下:
1、永久代受到JVM本身设置的固定大小限制,无法进行调整,而元空间使用的是直接内存,受本机可用内存的限制,虽然元空间仍旧可能溢出,但是比永久代出现的几率会更小。
2、永久代的对象是通过FullGC进行垃圾收集,也就是和老年代同时实现垃圾收集。替换成元空间以后,简化了Full GC。可以在不进行暂停的情况下并发地释放类数据,同时也提升了GC的性能。
3、在JDK1.8,合并HotSpot和JRockit的代码时, JRockit从来没有一个叫永久代的东西, 合并之后就没有必要额外的设置这么一个永久代的地方了。

标签:Java,虚拟机,线程,内存,JVM,方法,结构
From: https://www.cnblogs.com/ayic/p/18074884

相关文章

  • Redis zset 底层结构
    Rediszset底层结构  概要  在Redis的五种主要数据类型中,zset(有序集合)类型可能是最复杂,但也是最强大的一种。zset不仅可以存储键值对,还可以为每个元素分配一个分数,然后根据这个分数进行排序。这使得Zset非常适合用于实现排行榜、时间线等功能。  一、Zset底层结......
  • 统一返回结构 ResponseResult
    //定义返回数据结构publicinterfaceIResult{IntegergetCode();StringgetMessage();}//常用结果的枚举publicenumResultEnumimplementsIResult{SUCCESS(2001,"接口调用成功"),VALIDATE_FAILED(2002,"参数校验失败"),COMMON_FAILED(2003,......
  • 使用符号回归优化电路结构
    原理作为一种一种监督学习方法,符号回归(symbolicregression)试图发现某种隐藏的数学公式,以此利用特征变量预测目标变量。编码方法公式可以写成S-表达式的形式,继而可以转化成一颗二叉树。在这个二叉树里,所有的叶节点都是变量或者常数,内部的节点则是函数。用同构的思想不难发现:电......
  • C#实现图的邻接矩阵和邻接表结构
    原文链接:https://blog.csdn.net/weixin_41883890/article/details/125517599本文介绍C#实现图的邻接矩阵和邻接表结构。逻辑结构分为两部分:V和E集合,其中,V是顶点,E是边。因此,用一个一维数组存放图中所有顶点数据;用一个二维数组存放顶点间关系(边或弧)的数据,这个二维数组称为邻接矩阵......
  • 04分支结构
    1<!DOCTYPEhtml>2<htmllang="en">3<head>4<metacharset="UTF-8">5<metaname="viewport"content="width=device-width,initial-scale=1.0">6<title>Document......
  • 05循环结构
    1<!DOCTYPEhtml>2<htmllang="en">3<head>4<metacharset="UTF-8">5<metaname="viewport"content="width=device-width,initial-scale=1.0">6<title>Document......
  • 2.1HTML5基本结构
      HTML5实际上不算是一种编程语言,而是一种标记语言。HTML5文件是由一系列成对出现的元素标签嵌套组合而成,这些标签以<元素名>的形式出现,用于标记文本内容的含义。浏览器通过元素标签解析文本内容并将结果显示在网页上,而元素标签本身并不会被浏览器显示出来。HTML5文档的基......
  • 内存操作函数
    1memcpy函数memcpy是内存操作函数,所在的头文件是#include<string.h>。1.1memcpy功能memcpy和strcpy有一点相似,但是strcpy只能进行字符串的拷贝,而它可以对各种类型都能进行拷贝,但是按字节去进行拷贝的,就比如你有2个整形数组:a1和a2;你想将a2里面四个元素拷贝进a1中,一个整形是4......
  • 电气材料结构与性能(二)
    本篇为西安交通大学本科课程《电气材料基础》的笔记。本篇为这一单元的第二篇笔记,上一篇传送门。电气材料的导电性能带的形成能级的分裂根据量子力学,原子的能级是量子化的,能带的形成从能级的分裂而来。下面以氢分子H2的形成来说明这一过程。当两个氢原子相靠近而形成......
  • 归并排序、快速排序——左神数据结构与算法Day2学习笔记C++版本(持续更新)
    递归行为        利用递归求整个数组的最大值,代码如下。intfind_Max(inta[],intL,intR){if(L==R){returna[L];}intmid=L+((R-L)>>1);//mid是数组的中点intleftMax=find_Max(a,L,mid);intrightMax......