深入理解java虚拟机

本博客所有内容为阅读《深入理解java虚拟机》小结,如有侵权,请联系删除。

运行时数据区域

线程共享的数据区

对于java应用程序来说,堆是虚拟机所管理的内存中最大的一块。虚拟机启动时创建,此内存的唯一目的就是存放对象实例。从内存分配的角度看,堆可以划分出多个线程私有的分配缓冲区(ThreadLocalAllocationBuffer,TLAB),以提升对象分配时的效率。
根据java虚拟机规范,堆可以处于物理上不连续的内存空间中,但在逻辑上应该被视为连续的。
java堆既可以是固定大小的,也可以是可扩展的,通过参数-Xmx和-Xms设定。如果在java堆中没有内存完成实例分配,并且堆也无法再扩展时,抛出OOM。

方法区

方法区存储已被虚拟机加载的类型信息、常量、静态变量、即时编译期编译后的代码缓存等数据。
方法区有一部分被划分为运行时常量池,用于存放编译期生成的各种字面量与符号引用,运行时常量池相对于class文件常量池有更好的动态性。

线程隔离的数据区

虚拟机栈

生命周期与线程相同,虚拟机栈描述的是java方法执行的线程内存模型,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
局部变量表存放了编译期可知的各种java虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型)和returnAddress类型(指向了一条字节码指令的地址)。
这些数据类型在局部变量表中的存储空间以局部变量槽(slot)来表示,其中64位长度的long和double类型的数据会占用两个槽,其余的数据类型只占用一个槽。局部变量表所需的内存空间在编译期完成分配,方法运行期间不会改变局部变量表的大小(槽的数量)。
java虚拟机规范中,对这个内存区域规定了两类异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出SOE(stackoverflowerror),如果虚拟机栈容量可以动态扩展,当栈扩展无法申请到足够的内存会抛出OOM(hotspot虚拟机不可以动态扩展)。

本地方法栈

与虚拟机栈类似,为虚拟机使用到native方法服务的。

程序计数器

程序计数器是一块较小的内存,它可以看作当前线程所执行的字节码的行号指示器。在java虚拟机的概念里面,字节码解释器工作时就是通过改变这个计数器的值来选取需要执行的字节码指令。因为java的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,因此每个线程都需要一个程序下计数器来保证线程切换之后能恢复到原来的位置,且这个计数器需要线程隔离。如果线程正在执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果线程正在执行的是一个native方法,则这个计数器的值应该为空(undefined),此内存区域是java虚拟机规范中唯一未指定任何OOM情况的区域。

直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,但是这部分也被频繁的使用,而且也可能导致oom,所以放在这里一起学习。
在jdk1.4中新加入了NIO(new Input/output)类,引入了一种基于通道(channel)与缓冲区(Buffer)的I/O方式,它可以使用native函数库直接操作堆外内存,然后通过一个存储在java堆里面的directByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在java堆和native堆中来回复制数据,设置-Xmx等参数信息时,如果忽略直接内存,使得各种内存区域总和大于物理内存限制,则会导致OOM。

来源:https://www.icode9.com/content-1-783401.html

(0)

相关推荐

  • 漫画:Java内存数据区域详解

    https://github.com/TangBean 漫画由小猿编写创作 仔细看下面的思维导图,我们先来获取一个直观的认识,然后再一个一个详细分析! 总共也就这么 5 个区(直接内存不属于 JVM ...

  • 一起来聊一聊JVM虚拟机

    java虚拟机概述和基本概念 堆.栈.方法区 了解虚拟机参数 java虚拟机的原理 所谓的java虚拟机,就是一台虚拟的机器.它是一款软件,用来执行一系列计算指令,大体上虚拟机可以分为系统虚拟机和程序 ...

  • Java 虚拟机运行时数据区详解

    本文摘自深入理解 Java 虚拟机第三版 概述 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟 ...

  • 终于搞懂了Java 8 的内存结构,再也不纠结方法区和常量池了!!

    java8内存结构介绍 java8内存结构图 虚拟机内存与本地内存的区别 java运行时数据区域 直接内存 常见问题 java8内存结构介绍 java虚拟机在jdk8改变了许多,网络上各种解释都有,在 ...

  • 《深入理解Java虚拟机》 Java对象的生命周期

    Java虚拟机运行时数据区 方法区:存储 类信息.常量.静态变量.即使编译器编译后的代码等数据,也有别名叫做非堆.  方法区其中有包含有 运行时常量池,用于存放编译期生成的各种字面量和符号引用.其中, ...

  • 深入理解Java虚拟机 &GC分代年龄

    转自:https://www.cnblogs.com/xiarongjin/p/8309839.html 堆内存 Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象. ...

  • 深入理解Java虚拟机系列笔记

    类加载过程 最近开始学习Java虚拟机,今天学习了类加载的三个过程,遂写一篇博客作为学习笔记 类加载子系统概述 类加载子系统作为JVM的一部分,负责将硬盘中的class字节码文件加载到JVM中.类加载 ...

  • 2021最新 Java虚拟机(JVM)面试题精选(附刷题小程序)

    推荐使用小程序阅读 为了能让您更加方便的阅读 本文所有的面试题目均已整理至小程序<面试手册> 可以通过微信扫描(或长按)下图的二维码享受更好的阅读体验! 目录 推荐使用小程序阅读 1. J ...

  • 最简单直接地理解Java软件设计原则之里氏替换原则

    理论性知识 定义 里氏替换原则,Liskov Substitution principle(LSP). 抽象定义是下面这样的 如果对每一个类型为T1的对象O1,都有类型为T2的对象O2,使得以T1定义 ...

  • Java跨平台原理与Java虚拟机(JVM)

    Java跨平台原理(字节码文件.虚拟机) C/C++语言都直接编译成针对特定平台机器码.如果要跨平台,需要使用相应的编译器重新编译. Java源程序(.java)要先编译成与平台无关的字节码文件(.c ...

  • Java虚拟机(JVM)面试题(2020最新版)

    大家好,我是CSDN的博主ThinkWon,"2020博客之星年度总评选'开始啦,希望大家帮我投票,每天都可以投多票哦,点击下方链接,然后点击'最大",再点击'投TA一票'就可以啦 ...

  • 2021Java进阶新篇章,深入java虚拟机第二版

    二.Spring生命周期的大胆猜测 这里分享一个阅读源码的小技巧:捉大放小,连蒙带猜!8字真言,我们在阅读源码过程中,因为你要知道,每一个被开源出来的优秀框架,其源码的体系都是极其庞大复杂的,我们不能 ...