JVM:Java内存区域与内存溢出异常
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内存区域与内存溢出异常的更多相关文章
- JVM内存区域与内存溢出异常
Java虚拟机在执行java程序时会把它所管理的内存会分为若干个不同的数据区域,不同的区域在内存不足时会抛出不同的异常. >>运行时数据区域的划分 (1)程序计数器程序计数器(Progra ...
- 深入理解java虚拟机系列(一):java内存区域与内存溢出异常
文章主要是阅读<深入理解java虚拟机:JVM高级特性与最佳实践>第二章:Java内存区域与内存溢出异常 的一些笔记以及概括. 好了開始.假设有什么错误或者遗漏,欢迎指出. 一.概述 先上 ...
- 深入理解java虚拟机---->java内存区域与内存溢出异常
2. java内存区域于内存溢出异常 2.1 概述: 对于C/C++而言,内存管理具有最高的权利,既拥有每一个对象的“所有权”,又担负着每一个对象生命开始到结束的维护责任. 对于java而言,则把内存 ...
- 第二章Java内存区域与内存溢出异常
第二章 Java内存区域与内存溢出异常 一.概述 对与Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每个new操作去写delete/free代码,不容易出现内存泄露和内存溢出问 题, ...
- 《深入理解java虚拟机》第二章 Java内存区域与内存溢出异常
第二章 Java内存区域与内存溢出异常 2.2 运行时数据区域
- 深入了解Java虚拟机(1)java内存区域与内存溢出异常
java内存区域与内存溢出异常 一.运行时数据区域 1.程序计数器:线程私有,用于存储当前所执行的指令位置 2.Java虚拟机栈:线程私有,描叙Java方法执行模型:执行方法时都会创建一个栈帧,存储局 ...
- 2.1 自动内存管理机制--Java内存区域与内存溢出异常
自动内存管理机制 第二章.Java内存区域与内存溢出异常 [虚拟机中内存如何划分,以及哪部分区域.什么样代码和操作会导致内存溢出.各区域内存溢出的原因] 一.运行时数据区域 Java虚拟机所管理的内存 ...
- 虚拟机--第二章java内存区域与内存溢出异常--(抄书)
这是本人阅读周志明老师的<深入理解Java虚拟机>第二版抄写的,有很多省略,不适合直接阅读,需要阅读请出门左转淘宝,右转京东,支持周老师(侵权请联系删除) 第二章java内存区域与内存溢出 ...
- 深入理解Java虚拟机之Java内存区域与内存溢出异常
Java内存区域与内存溢出异常 运行时数据区域 程序计数器 用于记录从内存执行的下一条指令的地址,线程私有的一小块内存,也是唯一不会报出OOM异常的区域 Java虚拟机栈 Java虚拟机栈(Java ...
- 深入理解Java虚拟机之图解Java内存区域与内存溢出异常
Java内存区域与内存溢出异常 运行时数据区域 程序计数器 用于记录从内存执行的下一条指令的地址,线程私有的一小块内存,也是唯一不会报出OOM异常的区域 Java虚拟机栈 Java虚拟机栈(Java ...
随机推荐
- selenium-ide-2.3.0 组件在foxfire45.0无法安装的问题
楼主在安装selenium-ide组件时,尝试了下面两种方式都无法安装: 1.在forfire浏览器进行拖拽安装,页面无任何跳转.拖拽后回车安装,也没任何效果 2.附件组件-从文件安装添加组件,添加了 ...
- Docker 容器间的单向连接
Docker 容器间的单向连接 前言 a. 本文主要为 Docker的视频教程 笔记. b. 环境为 CentOS 7.0 云服务器 c. 上一篇:Dockerfile 自动制作 Docker 镜像( ...
- 3.17学习总结.listview用法总结
今天复习了listview控件的用法. 1.activity_main.xml 中的代码,如下: <?xml version="1.0" encoding="utf ...
- Docker安装flink及避坑指南
Docker安装flink 导航 无处不在的大数据 安装flink 拉取flink镜像 编写docker-compose.yml 生成启动 查看安装效果 常见坑及解决方案 问题1 问题2 参考 本 ...
- SpringCloudAlibaba - 整合 Nacos 实现服务注册与发现
目录 前言 环境 Nacos是什么? 服务发现原理 搭建 Nacos Server Nacos Server 下载地址 Nacos Server 的版本选择 运行 Nacos Server Nacos ...
- Jmeter扩展组件开发(9) - 解决空指针问题
问题分析 上一节https://www.cnblogs.com/gltou/p/14967005.html功能描述内容为空,导致Jmeter报空指针 CODE List desc = new Arra ...
- php/awk 处理csv 使用 SplFileObject 操作文件
取第5列,去掉开头结尾的引号,匹配以http://, https://, ftp://开头的行 * awk awk -F"," 'str=gsub(/(^\"*)|(\& ...
- Java面试总结 Boss沟通过:500+,面试:20,已投简历130+
1 概述 1 介绍 最近换工作,对最近面试的过程进行总结,总结每个公司的面试流程和问到的面试题,记录自己,也供大家参考. 我是一名Java开发,工作经验10年,所以面试一名高级Java开发工程师. 简 ...
- 鸿蒙内核源码分析(调度队列篇) | 内核有多少个调度队列 | 百篇博客分析OpenHarmony源码 | v6.05
百篇博客系列篇.本篇为: v06.xx 鸿蒙内核源码分析(调度队列篇) | 内核有多少个调度队列 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度 ...
- Redis之品鉴之旅(二)
2)hash类型,上代码 using (RedisClient client = new RedisClient("127.0.0.1", 6379, "12345&qu ...