C++程序员肩负着每一个对象生命周期开始到终结的维护责任。Java程序员则可以借助自动内存管理机制,不需要自己手动去释放内存。由虚拟机进行内存管理,不容易出现内存泄漏和内存溢出的问题,但是一旦出现这些问题,就需要我们了解虚拟机的原理,才能排查解决这些内存问题。另外,jvm也是面试中常问的问题,因此我希望在者一系列的博客中进行相关内容的梳理。

jvm的知识主要分成三大板块:运行时数据区与垃圾回收,类的加载机制(重点是双亲委派模型等),Java内存模型与线程。

对于第一部分运行时数据区与垃圾回收,下面这个脑图总结的不错(来自朋友分享,未知出处,如果作者介意请在下方评论,我回删掉它)。

本篇是第一篇,首先来看一下什么是内存溢出?什么是内存泄漏?它们之间有什么区别和联系?

内存溢出和内存泄漏

内存溢出:程序运行过程中无法申请到足够内存,导致的错误。内存溢出通常发生与OLD段(老年代)或Perm段(永久代)垃圾回收后,仍然无内存空间容纳新的java对象的情况。

内存泄漏:程序中动态分配内存给一些临时对象,但是对象不会被GC回收,所以始终占用内存。及被分配的对象可达,但已经无用(由于主流的java虚拟机是通过可达性分析算法来标记垃圾对象的,因此如果是可达的对象,就不会被标记为垃圾,也不会被回收)

内存溢出与内存泄漏的关系:内存泄漏是内存溢出的一种原因。大量的内存泄漏会导致内存溢出。当然,内存溢出也可能是其他原因所导致的。

这里先简单介绍这两个概念,后续会有专门的博客阐述。


程序计数器(Program Counter)

注意:下文中凡是线程私有的运行时数据区,都不会涉及线程同步的问题。

程序技术器是线程私有的(为了线程切换后能恢复正确的执行位置,因此它必须是线程私有的)

作用:指示和记录线程的执行情况,字节码解释器工作时通过改变这个计数器的数值来选取下一条需要执行的字节码指令。它是当前线程所执行字节码的行号指示器。

注意:是唯一一个不会出现OOM异常的区域。

如果线程正在执行一个java方法,则这个计数器记录的是正在执行的虚拟机字节码的指令地址。如果是native方法,则该计数器为空。


虚拟机栈和本地方法栈 :

特点:线程私有

虚拟机栈的功能:每个方法在执行的时候都会在虚拟机栈中创建一个栈帧。栈帧存储内容:局部变量表,操作数栈,动态链接,方法出口等信息。每个方法执行到完成就对应了栈帧的压栈和出栈

注意,由于局部变量表是存放在虚拟机栈中,而虚拟机栈是线程私有的,所以局部变量都是线程安全的,局部变量不存在同步问题。

本地方法栈与虚拟机栈的区别:本地方法栈为native方法服务,虚拟机栈为java方法(也就是字节码)服务,有的虚拟机直接把这两个栈合二为一。

可能出现的异常:StackOverflowError和OutOfMemoryError


Java堆

特点:线程共享,java虚拟机管理内存中的最大一块内存。是垃圾收集器管理的主要区域。

作用:所有的对象实例和数组都在堆上分配内存。

现代收集器都采用分代收集算法,从内存回收角度看,可以分成新生代和老年代。

java堆可以处于物理上不连续的内存空间,只要逻辑上连续即可。

可能出现的异常:在堆中没有多余内存完成实例分配,而且堆也无法扩展时,将会抛出OutOfMemoryError异常。


方法区与运行时常量池

特点:线程共享。

功能作用:存放已经被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

java虚拟机规范对方法区的限制非常宽松。可以和堆一样不需要连续内存和可以选择固定大小和可扩展。,还可以选择不实现垃圾收集。方法区内存回收目标是针对常量池的回收和对类型的卸载。

方法区和运行时常量池可能出现的异常:OutOfMemoryError

运行时常量池:

功能:运行时常量池是方法区一部分,用于存放编译期生成的各种字面量和符号引用。翻译出来的直接引用也存储在运行时常量池中

特点:动态性。常量不一定只有编译期才能产生,运行期间也可能将新的常量放入池中。


直接内存

不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域。

jdk1.4引入了NIO,可以通过基于通道和缓冲区的IO方式,使用native函数库直接分配堆外内存(NIO也是一个重点,后续会有专门博客阐述)。这里我们只需要知道NIO是可以在堆外创建直接内存的。

可能出现的异常:OutOfMemoryError。


参考:https://blog.csdn.net/u012813201/article/details/73793668

   深入理解jvm

jvm系列(一)运行时数据区的更多相关文章

  1. JVM学习笔记-运行时数据区

    不同于C,C++程序,Java程序的内存管理工作由Java虚拟机(JVM)接管,这减低了java程序员的负担,但如果出现内存泄露与溢出问题如报OutOfMemory,StackOverFlow异常错误 ...

  2. 1、JVM 内存模型+运行时数据区+JVM参数

    JMM(内存模型)  1.’主内存+每个线程有自己的内存 JVM运行时数据区 包含:1.程序计算器(每个线程自带):2.JAVA-STACK(每个线程自带):3.本地方法stack:4.堆:5.方法区 ...

  3. jvm内存模型(运行时数据区)

    运行时数据区(runtime data area) jvm定义了几个运行时数据区,这些运行时数据区存储的数据,供开发者的应用或者jvm本身使用.按线程共享与否可以分为线程间共享和线程间独立. 线程间独 ...

  4. JVM三部曲之运行时数据区 (第一部)

    在接下来的几天想总结下,JVM相关的一些内容,比如下面的这三个内容算是比较核心知识点了 1.运行时数据区域: 在运行时数据区里存储类Class文件元数据(方法区),对象和数组(堆),方法参数局部变量( ...

  5. JVM内存结构——运行时数据区

    在Java虚拟机规范中将Java运行时数据划分为6种,分别为: PC寄存器(程序计数器) Java栈 堆 方法区 运行时常量池 本地方法栈 一.PC寄存器(程序计数器) PC寄存器(Program C ...

  6. JVM之Java运行时数据区(线程隔离区)

    来源 JVM会在会在执行Java程序过程中把所管理的内存划分为若干区域,主要包括程序计数器(Program Counter Register),虚拟机栈(VM Stack),本地方法栈(Native ...

  7. JVM之Java运行时数据区(线程共享区)

    JVM运行时区域各线程共享的区域包括堆区和方法区. 堆区 堆区最最主要的功能是存储对象实例[上篇也提到过],因此Java垃圾回收的主要战场就是在堆区,因此也有称为GC堆区.如果堆区的内存不够会出现Ou ...

  8. 【转】Java运行时数据区简介及堆与栈的区别

    理解JVM运行时的数据区是Java编程中的进阶部分.我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机 ...

  9. JVM系列之四:运行时数据区

    1. JVM架构图 Java虚拟机主要分为五大模块:类装载器子系统.运行时数据区.执行引擎.本地方法接口和垃圾收集模块. 2. JDK1.7内存模型-运行时数据区域 根据<Java 虚拟机规范( ...

随机推荐

  1. CF618F Double Knapsack

    题意简化 给定两个大小为 n 的集合A,B,要求在每个集合中选出一个子集,使得两个选出来的子集元素和相等 元素范围在 1~n ,n<=1e5 题目连接 题解 考虑前缀和 令A集合的前缀和为SA, ...

  2. 基于tensorflow的文本分类总结(数据集是复旦中文语料)

    代码已上传到github:https://github.com/taishan1994/tensorflow-text-classification 往期精彩: 利用TfidfVectorizer进行 ...

  3. 2020 年TI 杯大学生电子设计竞赛E题总结(放大器非线性失真研究装置)

    2020年TI杯大学生电子设计竞赛E题总结(放大器非线性失真研究装置) 摘要:E题的竞赛内容主要是参赛者自己搭建一个晶体管放大器,能够产生不失真.顶部失真.底部失真.双向失真和交越失真五种波形,并分别 ...

  4. 水题挑战4: luogu P1280 尼克的任务

    题目描述 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成. 尼克的一个工作日为 \(n\) 分钟,从 ...

  5. 写文档太麻烦,试试这款 IDEA 插件吧!

    前言 每次开发完新项目或者新接口功能等,第一件事就是提供接口文档.说到接口文档,当然是用 Markdown 了.各种复制粘贴字段,必填非必填,字段备注,请求返回示例等等.简直是浪费时间哇.所以想到了开 ...

  6. How to refresh datasource args caller[X++]

    To refresh  datasource args caller, you must add override method close on form like source code belo ...

  7. Spring Boot API 统一返回格式封装

    今天给大家带来的是Spring Boot API 统一返回格式封装,我们在做项目的时候API 接口返回是需要统一格式的,只有这样前端的同学才可对接口返回的数据做统一处理,也可以使前后端分离 模式的开发 ...

  8. 为什么要谨慎使用Arrays.asList、ArrayList的subList?

    1. 使用Arrays.asList的注意事项 1.1 可能会踩的坑 先来看下Arrays.asList的使用: List<Integer> statusList = Arrays.asL ...

  9. streamreader

    using (StreamReader sr = new StreamReader(@"C:\Documents and Settings\Administrator\桌面\1.txt&qu ...

  10. 文科妹子都会用 GitHub,你这个工科生还等什么

    在某乎上刷到一条关于 GitHub 的留言,如下: 点赞人数还不少,这说明还真有不少工科生不会用 GitHub,你看大小写都没有区分(手动狗头).所以我就想写篇文章科普下,"新手如何使用 G ...