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. python实现密码破解

    排列组合(破解密码) 关注公众号"轻松学编程"了解更多. 1.排列 itertools.permutations(iterable,n) 参数一:要排列的序列, 参数二:要选取的个 ...

  2. JDK8中的新时间API:Duration Period和ChronoUnit介绍

    目录 简介 Duration Period ChronoUnit 简介 在JDK8中,引入了三个非常有用的时间相关的API:Duration,Period和ChronoUnit. 他们都是用来对时间进 ...

  3. 835. Image Overlap —— weekly contest 84

    Image Overlap Two images A and B are given, represented as binary, square matrices of the same size. ...

  4. How to Convert and Import VHD to VMDK (VMWare)

    VHD or Virtual Hard Disk is the disk image format used by Microsoft virtualization software such as ...

  5. 3、编程语言与Python介绍

    一 引子 基于上一章所学,有了计算机硬件,再在硬件之上安装好操作系统,我们就有了一个应用程序的运行平台,我们接下来的任务就是学习如何使用某款编程语言来开发应用程序. 本章的主题是先了解一下编程语言,然 ...

  6. python-找不到tk包

    找不到-tk包 直接sudo apt-get install python3-tk 或者sudo apt-get install python-tk 百度上的方法不可信,还是直接这样一句命令来的实在

  7. 2012年游戏软件开发独立本科段01B0815自考科目

    01B0815自考科目 课程代码[学分] 课程名称 03708[02] 中国近现代史纲要 03709[04] 马克主义基本原理概论 03684[10] 综合英语(四) 01042[05] 应用数学 0 ...

  8. IDEA与Eclipse创建struts项目

    1.IDEA创建struts项目 这里再构建struts项目是选择jar包出问题了,可以重新配置 创建页面和action配置struts.xml 启动tomcat,浏览器中运行 具体参考: https ...

  9. mysql 触发器的创建和使用

    什么是触发器 触发器(TRIGGER)是MySQL的数据库对象之一,从5.0.2版本开始支持.该对象与编程语言中的函数非常类似,都需要声明.执行等.但是触发器的执行不是由程序调用,也不是由手工启动,而 ...

  10. UNP——第二章,TCP状态,TIME_WAIT

    状态可以用 netstat 验证 加粗线为 数据交换. 可以看出,TCP在 建立连接和 关闭连接,耗费资源, 因为UDP只需要两次数据通信即可. 但UDP没有可靠传输,和流量控制. 上面协商的MSS为 ...