那么我们在开始介绍Java内存区域之前,我们先放一张内存区域的图,方便我们后面介绍的时候可以对照着看。

须知,本文是根据JDK8来介绍的。

程序计数器

首先它是线程私有的,它也称为代码的行号指示器,字节码解释器就是通过改变程序计数器的位置来确定下一行要执行的代码,它不存在OOM。

如果线程正在执行一个Java方法,那么它记录的是正在执行虚拟机字节码指令的地址,如果是一个本地方法那么它的值为空。

Java虚拟机栈

它也是线程私有的,它的声明周期和线程一致。每个线程创建时都会创建一个虚拟机栈,内部保存了一个个的栈帧,每个栈帧就对应着一次方法的调用。既然知道了虚拟机栈里面存放的是一个个的栈帧,那么也不难猜出虚拟机栈里面都存储了什么东西。

Java虚拟机栈是存在OOM的,当线程所请求的栈的深度大于虚拟机栈的深度或者虚拟机栈可以动态扩容,当栈扩展时无法申请到足够的内存时,就会抛出OOM。

  • 虚拟机栈内部结构

  • 局部变量表

    主要存储方法的参数,所有的基本类型数据和对象地址,以及返回地址类型(return address)。它以变量槽为最小的存储单位,Java虚拟机并没有规定一个变量槽占用多少内存空间,但是规定了一个变量槽可以存放一个32位以内的数据类型。如果存储的数据类型超过32位,比如long、double,那么就使用两个变量槽进行存储。

  • 操作数栈

    操作数栈是一个先进后出的操作数栈,当一个方法刚开始执行的时候,一个新的栈帧也会随之被创建出来,这个方法的操作数栈是空的,它主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。如果被调用的方法有返回值,那么返回值将会被压入当前栈帧的操作数栈中。操作数栈并非采用索引的方式进行数据访问,而是通过入栈(push)和出栈(pop)操作来完成数据的访问。

  • 动态链接

    大白话就是,栈帧中保存了一个方法的引用,当执行方法的时候,可以拿着这个引用到运行时常量池中找到这个方法。

    动态链接的作用就是将这些方法的符号引用转换为调用方法的直接引用。

  • 方法返回地址

    就是在方法执行结束之后,要返回下一条要执行代码位置的值,也就是程序计数器的值。

    那么除了方法正常执行结束退出外,还有另外一种情况就是异常导致的方法退出,那么这种情况下是不会返回任何值的。对于抛出的异常,栈帧中不会做任何记录,但是会记录在一个异常表中。

本地方法栈

Java虚拟机栈为虚拟机执行Java方法服务,本地方法栈则为虚拟机使用到的本地方法服务。像JVM就有好多C语言写的方法,这个就需要本地方法栈来执行。

Java堆

Java堆是虚拟机中最大的一块内存空间,它被所有的线程共享,在虚拟机启动时创建。它唯一的目的就是存放对象实例。

如果面试被问到,所有的对象实例都是在堆中分配内存吗?这个时候你一定要回答,不是。

随着即时编译技术的发展进步,尤其是逃逸分析技术的日渐强大,栈上分配、变量替换等优化手段,让实例在”只在堆“中分配不再成为绝对。

Java堆是垃圾收集的主要区域,Java堆中也经常出现新生代、老年代、永久代等等,这里需要注意,这些并不是Java堆物理上的内存布局,它是作为垃圾收集器而划分一种内存布局。

方法区

方法区也是线程共享的区域,它主要用于存储被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

方法区它是可以被垃圾收集器进行回收的,主要针对类型的卸载和常量池的回收。

方法区也可以产生OOM,当方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。

运行时常量池

运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等信息外,还有一项信息是常量池表,它用来存储编译期生成的各种字面量和符号引用。

如果动态链接那块没看懂,那么看了运行常量池再翻回去看看是不是好理解了。

一文看懂JVM内存区域分布与作用的更多相关文章

  1. 一文搞懂JVM内存结构+GC

    一.jvm是干什么的? 大家都知道java是跨平台语言,一次编译可以在不同操作系统上运行,怎么做到的呢,看下图: javac把写的源代码(java文件),编译成字节码(class文件),字节码部署到l ...

  2. 一文搞懂jvm内存结构

    一.jvm是干什么的? 大家都知道java是跨平台语言,一次编译可以在不同操作系统上运行,怎么做到的呢,看下图: javac把写的源代码(java文件),编译成字节码(class文件),字节码部署到l ...

  3. 小白也能看懂的JVM内存区域

    前言 最近在准备面试题刷到了JVM这块,作为一个小白,巩固知识点最好的方式就是亲手写出来并分享:相信我的理解,同样是小白的你,一定有很大的帮助.不信,请你往下看! JVM内存区域简介 如果有人问Jav ...

  4. 一文看懂大数据的技术生态圈,Hadoop,hive,spark都有了

    一文看懂大数据的技术生态圈,Hadoop,hive,spark都有了 转载: 大数据本身是个很宽泛的概念,Hadoop生态圈(或者泛生态圈)基本上都是为了处理超过单机尺度的数据处理而诞生的.你可以把它 ...

  5. 谈谈JVM内存区域的划分

    我们知道,计算机CPU和内存的交互是最频繁的,内存是我们的高速缓存区,用户磁盘和CPU的交互,而CPU运转速度越来越快,磁盘远远跟不上CPU的读写速度,才设计了内存,用户缓冲用户IO等待导致CPU的等 ...

  6. [转帖]一文看懂mysql数据库本质及存储引擎innodb+myisam

    一文看懂mysql数据库本质及存储引擎innodb+myisam https://www.toutiao.com/i6740201316745740807/ 原创 波波说运维 2019-09-29 0 ...

  7. 一文看懂Java序列化

    一文看懂Java序列化 简介 Java实现 Serializable 最基本情况 类的成员为引用 同一对象多次序列化 子父类引用序列化 可自定义的可序列化 Externalizable:强制自定义序列 ...

  8. 初始jvm(一)---jvm内存区域与溢出

    jvm内存区域与溢出 为什么学习jvm 木板原理,最短的一块板决定一个水的深度,当一个系统垃圾收集成为瓶颈的时候,那么就需要你对jvm的了解掌握. 当一个系统出现内存溢出,内存泄露的时候,因为你懂jv ...

  9. JVM内存区域划分及垃圾回收

    第一部分.闲扯+概述 近来在研读<深入理解java虚拟机>一书,读完之后做个小结,算是记录一下自己的学习所得,在成长的路上,只能死磕. 要理解JVM,就要先从其内存区域划分开始,知道其由几 ...

随机推荐

  1. Abp Vnext3 vue-admin-template(三获取用户信息)

    因为获取用户比较简单,只需要把用户名及头像地址赋值即可(也许理解错误,如果发现请告知谢谢), 首先将src\api\usr.js中的url请求地址改为以下代码 export function getI ...

  2. RSA及其证明 [原创]

    描述RSA的实现步骤介绍文章非常多,但说明并证明其原理,并进而讨论为什么这样设计的文章不多.本人才疏学浅,不敢说理解了R.S.A.三位泰斗的设计初衷,简单就自己的理解写一写,博大家一笑. 以下原创内容 ...

  3. SQL语句分组获取记录的第一条数据的方法

    使用Northwind 数据库 首先查询Employees表 查询结果: city列里面只有5个城市 使用ROW_NUMBER() OVER(PARTITION BY COL1 ORDER BY CO ...

  4. DFS与DFS迷宫问题

    一天蒜头君掉进了一个迷宫里面,蒜头君想逃出去,可怜的蒜头君连迷宫是否有能逃出去的路都不知道. 看在蒜头君这么可怜的份上,就请聪明的你告诉蒜头君是否有可以逃出去的路. 输入格式 第一行输入两个整数n 和 ...

  5. 【OI】C++STL 不定长数组 vector

    Vector 本来是向量的意思,只不过在用法上类似于一个不限长度的数组. 定义语法:vector<数据类型> 名称; 一.头文件:<vector> (bits/stdc++请忽 ...

  6. Jenkins持续交付实战演练

    jenkins web hook机制 运行jenkins任务触发方式: 主动运行 定时构建 就算代码库没有更新,也会构建. 通过代码库主动触发Jenkins的构建任务 jenkins向外暴露一个触发器 ...

  7. Windows下升级Python3.7.7后(原Python3.6.2版本)如何切换Python版本

    笔者:风起怨江南 出处:https://www.cnblogs.com/mengjinxiang 笔者原创,文章欢迎转载,如果喜欢请点赞+关注,谢谢! 问题:window系统下,如果升级了最新的Pyt ...

  8. PolarDB PostgreSQL 快速入门

    什么是PolarDB PostgreSQL PolarDB PostgreSQL(下文简称为PolarDB)是一款阿里云自主研发的云原生数据库产品,100%兼容PostgreSQL,采用基于Share ...

  9. P3170-[CQOI2015]标识设计【插头dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P3170 题目大意 给出\(n*m\)的网格上有一些障碍,要求用三个\(L\)形(高宽随意,不能退化成线段/点)覆盖 ...

  10. list集合根据字段分组统计转换成map

    前言 表格需要对数据进行统计 代码实现 public Map getUnitStoreSum(String unitId, String billCode) { List store=listUnit ...