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#动态构建表达式树(三)——表达式的组合

    C#动态构建表达式树(三)--表达式的组合 前言 在筛选数据的过程中,可能会有这样的情况:有一些查询条件是公共的,但是根据具体的传入参数可能需要再额外增加一个条件.对于这种问题一般有两种方法: a. ...

  2. CodeForce-782B The Meeting Place Cannot Be Changed(高精度二分)

    https://vjudge.net/problem/CodeForces-782B B. The Meeting Place Cannot Be Changed time limit per tes ...

  3. VBox 虚拟机安装 Openwrt 做旁路由

    VBox 虚拟机安装 Openwrt 做旁路由 需求:开个虚拟机做旁路由,电脑把网关设置成旁路由地址,用它跑个上网或其他什么东西. 安装及配置过程简述 这件事流程很简单,总结起来主要有以下几点: 安装 ...

  4. 成本降低40%、资源利用率提高20%的 AI 应用产品云原生容器化之路

    作者 郭云龙,腾讯云高级工程师,目前就职于 CSIG 云产品三部-AI 应用产品中心,现负责中心后台业务框架开发. 导语 为了满足 AI 能力在公有云 SaaS 场景下,服务和模型需要快速迭代交付的需 ...

  5. PHP中的MySQLi扩展学习(二)mysqli类的一些少见的属性方法

    虽说是少见的一些属性方法,但是可能还是有不少同学在日常的开发中使用过,这里只是学习了可能相对来说我们用得比较少的一些 mysqli 的属性或方法.就当是扩展一下自己的知识体系. 切换用户 首先就是切换 ...

  6. video.js视频播放插件

    1 初始化 Video.js初始化有两种方式. 1.1 标签方式 一种是在<video>标签里面加上class="video-js"和data-setup='{}'属性 ...

  7. 最新seo优化技巧

    国内的SEO也发展不少年份了.我是最早开始从事SEO的那一班人.看着这个行业从零开始发展,长大.成熟还谈不上.可以这样说吧,国内做这个行业的,高手并不多.实战的高手更是寥寥无几.当然这个是我个人的推断 ...

  8. hashCode 和 equals 的区别

    今天记录一下hashCode的知识,以前都没有怎么接触过的,感觉还是很陌生,专门去学习了一下 首先我最大的问题就是hashCode究竟是干什么 的,现在也一知半解了吧, 哈希值是一个对象的地址值,是一 ...

  9. nginx 配置文件(支持thnkphp3.2~5)

    server { listen 8080 ; server_name localhost; set $root /var/www/myweb; #listen 443 ssl; #ssl_certif ...

  10. vue+element实现省区市三级联动以及详细地址的输入

    Vue+elementui实现省区市三级联动+详细地址的输入 详细需求,需要手动更改用户所在的地址. 安装依赖项 npm install element-china-area-data -S 在组建中 ...