Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁时间,有些区域随着虚拟机进程的启动而存在,有些区域依赖用户线程的启动和结束而建立和销毁。

Java 虚拟机运行时数据区:

程序计数器:

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

如果执行的是一个 Java 方法,这个计数器记录的是正在执行的字节码指令的地址;若是 Java 的 Native 方法,计数器值为空。此外,这个区域是 Java 虚拟机规范中唯一一个没有 OutOfMemoryError 异常的区域。

Java虚拟机栈:

和程序计数器一样是线程私有的,生命周期与线程相同,它所描述的是 Java 方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(用于存储局部变量表、操作栈数、动态链接、方法出口等),压入栈中,当每一个方法执行完,对应的栈帧就会从虚拟机栈中弹出。

局部变量表中存放编译期中已知各种基本的数据类型、对象的引用(指向对象的引用指针、句柄或者其相关的地址)和 returnAddress 类型。局部变量表需要的内存空间在编译期间完成分配,当进入一个方法时,栈帧中所需要分配多大的局部变量表空间是确定的,运行期间其大小不会改变。

Java 虚拟机规范中在这规定了有两个异常:StackOverflowError(请求的栈深度超过栈的深度时) 和 OutOfMemoryError(可动态扩展但内部空间不足的时候)。

本地方法栈:

与虚拟机栈发挥的作用非常相似,它们之间的区别不过是虚拟机栈为虚拟机执行 Java 方法(字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。

在虚拟机规范中对本地方法栈中方法使用的语言、数据结构并没有强制规定,虚拟机可以自由的实现它。HotSpot虚拟机直接把本地方法栈和虚拟机栈合二为一。可能会抛出的异常和虚拟机栈一样。

Java 堆(Heap):

它是虚拟机管理的内存中最大的一块地方。Java 堆是被所有线程共享的一块内存区域,在虚拟机启动是创建。其目的是就会存放 Java 对象的实例(几乎所有实例在这里分配内存)。

它也是垃圾收集器管理的主要区域。现在收集器基本都采用分代算法,Java 堆可以分为新生代和老年代,再细一点新生代有 Eden 空间、From Survivor 空间、To Survivor 空间。

在这里提一下永久带 PermGen(存放类的元数据,在heap中,不是所有虚拟机都有永久带概念),在 HotSpot VM 中,存在于 JDK 8 之前的版本,在 JDK 8 以及之后,永久带被移除,相对引入了一个新的内存区域(本地内存中)叫 Metaspace(元空间)。

从 Java 8 中删除 PermGen 的原因:

PermGen有很多缺点:

  • 启动时固定大小:难以调整,所需的大小取决于类的数量,方法的大小,常量池的大小。
  • 内部热点类型是 Java 对象:可以完整的 GC 进行移动,不透明的,不是强类型且难以调试的元数据一起移动。
  • 简化完整集合:为每个集合添加了用于元数据的特殊迭代器。
  • 现在,无需并发GC暂停,就可以同时取消分配类数据。
  • PermGen 限制的未来改进实现。

MetaSpace 的优势:

在性能和内存管理方面,MetaSpace 有很多优势:

  • 利用Java Specification属性:类和关联的元数据生存期与类加载器匹配。
  • 每个加载器存储区域:元空间
  • 仅线性分配。
  • 没有单独的回收(重定义类和类加载失败除外)
  • 没有GC扫描或压缩。
  • 没有元空间对象的重定位。

元空间调整

要设置最大元空间大小,可以使用-XX:MaxMetaspaceSize标志,并且默认情况下根据机器内存限制是无限的。如果未指定此最大限制标志,则Metaspace将根据运行时的应用程序需求动态调整大小。
此更改将在将来实现其他优化和功能

    • 应用程序类数据共享。
    • 年轻的收藏优化,G1类卸载。
    • 元数据大小减少和内部JVM占用空间项目。

方法区:

和Java堆一样,是各个线程共享的内存区域,用于存储虚拟机加载的类信息、常量、静态常量、即时编译后的代码等数据。Java虚拟机规范把方法区(Non-Heap)和Java堆区分开来。内存无法满足时会跑出OutOfMemoryError。

运行时常量池:

方法区的一部分。Class文件除了有累的版本、字段、方法、接口等描述信息外,还有一项是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池存放。

 

JVM:Java内存区域与内存溢出异常的更多相关文章

  1. JVM内存区域与内存溢出异常

    Java虚拟机在执行java程序时会把它所管理的内存会分为若干个不同的数据区域,不同的区域在内存不足时会抛出不同的异常. >>运行时数据区域的划分 (1)程序计数器程序计数器(Progra ...

  2. 深入理解java虚拟机系列(一):java内存区域与内存溢出异常

    文章主要是阅读<深入理解java虚拟机:JVM高级特性与最佳实践>第二章:Java内存区域与内存溢出异常 的一些笔记以及概括. 好了開始.假设有什么错误或者遗漏,欢迎指出. 一.概述 先上 ...

  3. 深入理解java虚拟机---->java内存区域与内存溢出异常

    2. java内存区域于内存溢出异常 2.1 概述: 对于C/C++而言,内存管理具有最高的权利,既拥有每一个对象的“所有权”,又担负着每一个对象生命开始到结束的维护责任. 对于java而言,则把内存 ...

  4. 第二章Java内存区域与内存溢出异常

    第二章 Java内存区域与内存溢出异常 一.概述 对与Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每个new操作去写delete/free代码,不容易出现内存泄露和内存溢出问 题, ...

  5. 《深入理解java虚拟机》第二章 Java内存区域与内存溢出异常

    第二章 Java内存区域与内存溢出异常 2.2 运行时数据区域  

  6. 深入了解Java虚拟机(1)java内存区域与内存溢出异常

    java内存区域与内存溢出异常 一.运行时数据区域 1.程序计数器:线程私有,用于存储当前所执行的指令位置 2.Java虚拟机栈:线程私有,描叙Java方法执行模型:执行方法时都会创建一个栈帧,存储局 ...

  7. 2.1 自动内存管理机制--Java内存区域与内存溢出异常

    自动内存管理机制 第二章.Java内存区域与内存溢出异常 [虚拟机中内存如何划分,以及哪部分区域.什么样代码和操作会导致内存溢出.各区域内存溢出的原因] 一.运行时数据区域 Java虚拟机所管理的内存 ...

  8. 虚拟机--第二章java内存区域与内存溢出异常--(抄书)

    这是本人阅读周志明老师的<深入理解Java虚拟机>第二版抄写的,有很多省略,不适合直接阅读,需要阅读请出门左转淘宝,右转京东,支持周老师(侵权请联系删除) 第二章java内存区域与内存溢出 ...

  9. 深入理解Java虚拟机之Java内存区域与内存溢出异常

    Java内存区域与内存溢出异常 运行时数据区域 程序计数器 用于记录从内存执行的下一条指令的地址,线程私有的一小块内存,也是唯一不会报出OOM异常的区域 Java虚拟机栈 Java虚拟机栈(Java ...

  10. 深入理解Java虚拟机之图解Java内存区域与内存溢出异常

    Java内存区域与内存溢出异常 运行时数据区域 程序计数器 用于记录从内存执行的下一条指令的地址,线程私有的一小块内存,也是唯一不会报出OOM异常的区域 Java虚拟机栈 Java虚拟机栈(Java ...

随机推荐

  1. C# 反射 + Quartz,实现流程处理

    场景: 前不久,公司里项目经理要求我实现流程处理,比如,用户可以定义一个定时任务,每周一查看报表.定时任务很简单,用Quartz可以实现,但是用户自己选择报表就比较麻烦,因为系统的不同模块的生成报表的 ...

  2. 剑指offer计划19( 搜索与回溯算法中等)---java

    1.1.题目1 剑指 Offer 64. 求1+2+-+n 1.2.解法 这题看评论区真的绝了,都是人才,各个说话都好听,我看到个还有用异常来结束的就离谱. 这题用了&&当左边为fal ...

  3. PHP中操作任意精度大小的GMP扩展学习

    对于各类开发语言来说,整数都有一个最大的位数,如果超过位数就无法显示或者操作了.其实,这也是一种精度越界之后产生的精度丢失问题.在我们的 PHP 代码中,最大的整数非常大,我们可以通过 PHP_INT ...

  4. composer 下载包慢

    方法一: 修改 composer 的全局配置文件(推荐方式) 打开命令行窗口(windows用户)或控制台(Linux.Mac 用户)并执行如下命令: composer config -g repo. ...

  5. html jquey的选择器checkbox,select

    1 判断checkbox是否选中 用到 jquery的 is方法 jquery: <div id="divId" class="divTable"> ...

  6. C博客作业00--顺序分支结构

    这个作业属于哪个班级 C语言--网络2011/2012 这个作业的地址 C博客作业00--顺序分支结构 这个作业的目标 初步认识C语法,掌握数据表达.printf.scanf语法及分支结构内容 0.展 ...

  7. canal源码之BooleanMutex(基于AQS中共享锁实现)

    在看canal源码时发现一个有趣的锁实现--BooleanMutex 这个锁在canal里面多处用到,相当于一个开关,比如系统初始化/授权控制,没权限时阻塞等待,有权限时所有线程都可以快速通过 先看它 ...

  8. 解决跨域、同源策略-React中代理的配置

    React中代理的配置 主要是解决同源策略的问题 何为同源策略? 因为我们React在3000端口,Vue在8080端口,而后台接口往往在5000,这种不同的端口之间就是一种跨域的问题了 axios发 ...

  9. Charles安装https证书

    Charles抓取https的包,出现unknow,需要安装https证书.

  10. Ubuntu18.04 安装Tomcat 8.5

    下载tomcat,登陆官网:https://tomcat.apache.org/ 点击tar.gz后,弹出这个不大懂这是什么? tomcat要求的jdk版本 解压tar包 sudo tar zxvf ...