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

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

JVM的内存结构

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

程序计数器

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

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

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从来没有一个叫永久代的东西, 合并之后就没有必要额外的设置这么一个永久代的地方了。

JVM(一)-内存结构的更多相关文章

  1. 巩固java(二)----JVM堆内存结构及垃圾回收机制

    前言:        我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制. 正文: 1.JVM堆内存结构   ...

  2. JVM的内存结构,JVM的回收机制

    内存作为系统中重要的资源,对于系统稳定运行和高效运行起到了关键的作用,Java和C之类的语言不同,不需要开发人员来分配内存和回收内存,而是由JVM来管理对象内存的分配以及对象内存的回收(又称为垃圾回收 ...

  3. JVM 垃圾回收机制和常见算法和 JVM 的内存结构和内存分配(面试题)

    一.JVM 垃圾回收机制和常见算法 Sun 公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同.GC(Garbage Collector)在回收对象前首先必 ...

  4. JVM之内存结构详解

    对于开发人员来说,如果不了解Java的JVM,那真的是很难写得一手好代码,很难查得一手好bug.同时,JVM也是面试环节的中重灾区.今天开始,<JVM详解>系列开启,带大家深入了解JVM相 ...

  5. JVM的内存结构以及性能调优

    JVM的内存结构以及性能调优 发布时间: 2017-11-22 阅读数: 16675 JVM的内存结构以及性能调优1:JVM的结构主要包括三部分,堆,栈,非堆内存(方法区,驻留字符串)堆上面存储的是引 ...

  6. JVM的基本结构和JVM的内存结构

    这里概要介绍一下JVM在启动后,作为操作系统的一个进程的基本结构,以及从操作系统角度看,JVM如何管理它从操作系统里申请来的内存的,也就是JVM的内存结构或者叫JVM内存模型. 1.JVM的基本结构 ...

  7. JVM:内存结构

    JVM:内存结构 说明:这是看了 bilibili 上 黑马程序员 的课程 JVM完整教程 后做的笔记 内容 程序计数器 虚拟机栈 本地方法栈 堆 方法区 直接内存 1. 程序计数器 1.1 定义 P ...

  8. JVM之内存结构

    JVM是按照运行时数据的存储结构来划分内存结构的.JVM在运行Java程序时,将他们划分成不同格式的数据,分别存储在不同的区域,这些数据就是运行时数据.运行时数据区域包括堆,方法区,运行时常量池,程序 ...

  9. Java中的JVM的内存结构

    Java的虚拟机自身结构图: JVM内存结构主要包括两个子系统和两个组件.两个子系统分别是Classloader子系统和Executionengine(执行引擎)子系统:两个组件分别是Runtimed ...

  10. JVM(一) 内存结构

    JVM内存结构 方法区(JDK8以上叫元空间)和堆为线程共享区,虚拟机栈.本地方法栈及程序计数器为线程独占区,  还有一个没有在下图中体现的叫做直接内存(Direct Memory),不受JVM GC ...

随机推荐

  1. 事务提交之后再执行某些操作 → 引发对 TransactionSynchronizationManager 的探究

    开心一刻 昨晚,小妹跟我妈聊天 小妹:妈,跟你商量个事,我想换车,资助我点呀 妈:哎呀,你那分扣的攒一堆都够考清华的,还换车资助点,有车开就不错了 小妹:你要是这么逼我,别说哪天我去学人家傍大款啊 妈 ...

  2. 【游戏】C语言实现扫雷游戏(超详细备注和解释)

    C语言实现扫雷游戏 求个赞求个赞求个赞求个赞 谢谢 先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️ 文章目 ...

  3. 【C语言深度解剖】一篇解决程序的环境【编译+链接详解】让面试官给我们竖起大拇指

    文章目录 程序的翻译环境 翻译环境详解 编译 预编译 编译 汇编 关于形成符号表 链接 运行环境 尾声 [C语言深度解剖][Linux操作系统]程序的环境[编译+链接详解] 那么这里博主先安利一下一些 ...

  4. Softmax偏导及BP过程的推导

    Softmax求导 其实BP过程在pytorch中可以自动进行,这里进行推导只是强迫症 A Apart证明softmax求导和softmax的BP过程 本来像手打公式的,想想还是算了,引用部分给出la ...

  5. Florr 从新手到大佬

    Florr 从新手到大佬 新手上路 首先在这里,你会遇到一些简单的教程.按照教程完成,也可以参考链接里的内容. 装备分为一下几种: $ \color{#7eef6D} \text{Common} $ ...

  6. XD刷机报错bad CRC

    测试需要,给一台1/4 rack的X8M HC刷机,使用oeda配置好的xml文件,执行命令列出本次刷机的所有步骤: [root@dbm11dbadm01 linux-x64]# ./install. ...

  7. 17.1 使用内存映射文件--《Windows核心编程》

    Windows 提供了以下三种机制来对内存进行操控虚拟内存:最适合用来管理大量对象数组或者大型数据结构内存映射文件:最适合用来管理大型数据流(通常是文件),以及在同一机器上运行的多个进程之间的共享数据 ...

  8. Delphi-判断一个对象是否释放,改造官方的Assigned

    直接上例子了,基础知识自己去了解,首先定义一个类: TPerson = class public name: string; age: Integer; constructor Create(name ...

  9. [Java]Map接口有关总结

    Map接口 1.HashMap和Hashtable的区别 线程安全方面.HashMap是非线程安全的,Hashtable是线程安全的.因为Hashtable内部方法基本都经过synchronized修 ...

  10. NC17890 方格填色

    题目链接 题目 题目描述 给一个m x n的方格,Applese想要给方格填上颜色,每个格子可以是黑色或者白色.他要求左右相邻两格不能同为白色且相邻两列不能全为黑色. 求满足条件的方案数. 输入描述 ...