JVM笔记【1】-- 运行时数据区

时间:2022-12-12 14:58:50

(一)java内存区域管理

C/C++每一个new操作都需要自己去delete/free,而java里面有虚拟机自动管理内存,不容易出现内存泄漏或者溢出的问题,但是不容易出现不代表不出现,了解虚拟机怎么使用和管理内存是十分重要的是,对程序优化或者问题排查有帮助。

运行时区域主要分为:

  • 线程私有:
    • 程序计数器:Program Count Register,线程私有,没有垃圾回收
    • 虚拟机栈:VM Stack,线程私有,没有垃圾回收
    • 本地方法栈:Native Method Stack,线程私有,没有垃圾回收
  • 线程共享:
    • 方法区:Method Area,以HotSpot为例,JDK1.8后元空间取代方法区,有垃圾回收。
    • 堆:Heap,垃圾回收最重要的地方。

JVM笔记【1】-- 运行时数据区

1.1 程序计数器

空间很小,当前线程执行的字节码的行号指示器(线程独有,指示当前执行到哪,下一步需要执行哪一个字节码),分支,循环,跳转,异常处理,线程恢复都需要依赖它。

线程私有:java多线程其实是线程轮流切换并分配处理器执行时间的方式实现,一个核一个具体的时间点,只会执行一个线程的指令。线程切换需要保存和恢复正确的执行位置(保护和恢复现场),所以不同的线程需要不同的程序计数器。

  • 执行java方法时,程序计数器记录的是正在执行的字节码指令地址
  • 执行Native方法,程序计数器为空

唯一一个没有规定任何OutOfMemory的区域,也没有GC(垃圾回收)。

1.2 虚拟机栈

线程私有,生命周期和线程一样,主要是记录该线程Java方法执行的内存模型。虚拟机栈里面放着好多栈帧。注意虚拟机栈,对应是Java方法,不包括本地方法。

一个Java方法执行会创建一个栈帧,一个栈帧主要存储:

  • 局部变量表
  • 操作数栈
  • 动态链接
  • 方法出口

    每一个方法调用的时候,就相当于将一个栈帧放到虚拟机栈中(入栈),方法执行完成的时候,就是对应着将该栈帧从虚拟机栈中弹出(出栈)。

每一个线程有一个自己的虚拟机栈,这样就不会混起来,如果不是线程独立的话,会造成调用混乱。

大家平时说的java内存分为堆和栈,其实就是为了简便的不太严谨的说法,他们说的栈一般是指虚拟机栈,或者虚拟机栈里面的局部变量表。

局部变量表一般存放着以下数据:

  • 基本数据类型(boolean,byte,char,short,int,float,long,double
  • 对象引用(reference类型,不一定是对象本身,可能是一个对象起始地址的引用指针,或者一个代表对象的句柄,或者与对象相关的位置)
  • returAddress(指向了一条字节码指令的地址)

局部变量表内存大小编译期间确定,运行期间不会变化。空间衡量我们叫Slot(局部变量空间)。64位的long和double会占用2个Slot,其他的数据类型占用1个Slot。

异常:

  • *Error:线程请求的栈深度大于虚拟机允许的深度
  • OutOfMemoryError:内存不足

1.3 本地方法栈

和虚拟机栈类似,对应本地方法,Native,虚拟机规范允许语言,使用方式和数据结构不同,有些可能将虚拟机栈和本地方法栈合并。

异常与虚拟机栈一致:

  • *Error:线程请求的栈深度大于虚拟机允许的深度
  • OutOfMemoryError:内存不足

1.4 java堆

堆是内存管理最大的一块,线程共享。

虚拟机规范中说,所有的对象实例和数组都要在堆上分配。但是实际上不是所有的对象都在堆上分配,这个和JIT编译器的发展和逃逸分析技术相关。Why?

// TODO

堆的细分:新生代,老年代,再细分有Eden,From survivor,To survivor等。

堆中也有可能有线程私有的区域,分配缓冲区。

物理上可以不连续,但是逻辑上是连续的。

异常:

  • OutOfMemoryError:内存不足

1.5 方法区

名为非堆,但是实际和堆一样,是线程共享的区域,主要存贮以下信息:

  • 已被虚拟机加载的类信息
  • 常量
  • 静态变量
  • 即时编译器编译后的代码

方法区不等于永久代,指示Hotspot虚拟机将GC分代收集拓展到方法区,也就是用永久代实现了方法区,而其他的虚拟机不一定,不是固定的。JDK1.7将永久代的字符串常量移出了。

方法区回收垃圾的效果不是很好,可以选择不回收,虚拟机可以决定,当然也可能发生内存泄漏。

异常:

  • OutOfMemoryError:内存分配异常

1.5.1 运行时常量池

运行时常量池时方法区的一部分,但是不是全部,Class文件主要包括:

  • 类的版本
  • 字段
  • 方法
  • 接口
  • 常量池,存放编译产生的字面量和符号引用,一般除了描述Class文件的符号引用,还有直接引用也在里面。是动态的,运行时可以产生,比如String.intern()方法。

异常:

  • OutOfMemoryError:内存分配异常

(二)直接内存

不是虚拟机运行时数据区,也不是规范规定的区域,但是使用频繁且可能会有OutOfMemoryError:内存分配异常出现。

比如,NIO(1.4)基于Channel与Buffer的I/O,可以用Native函数直接分配堆外内存,通过存储在Java堆中的DirectByteBuffer对象作为引用来操作,提高性能,不需要Java堆和Native堆都来回复制数据。

直接内存受物理的内存,或者处理器寻址空间之类的限制。

本文系JVM学习相关笔记,整理来自周志明老师的《深入理解Java虚拟机》,无比钦佩,强烈推荐!

【作者简介】

秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。这个世界希望一切都很快,更快,但是我希望自己能走好每一步,写好每一篇文章,期待和你们一起交流。

此文章仅代表自己(本菜鸟)学习积累记录,或者学习笔记,如有侵权,请联系作者核实删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有错误之处,还望指出,感激不尽~

JVM笔记【1】-- 运行时数据区

JVM笔记【1】-- 运行时数据区的更多相关文章

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

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

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

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

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

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

  4. 《深入理解Java虚拟机》笔记01 -- 运行时数据区

    运行时数据区示意图 1. 程序计数器 占用一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.主要用来记录线程执行到哪条语句了,分支.循环.跳转.异常处理.线程恢复等功能都需要依赖这个 ...

  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学习笔记-运行时数据区

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

随机推荐

  1. 【Alpha阶段】第五次Scrum例会

    由于软工整个项目规划延期1周,我们将停止2天的Scrum,进行相应的修整 会议信息 时间:2016.10.21 22:30 时长:20min 地点:大运村1号公寓5楼楼道 类型:日常Scrum会议 个 ...

  2. springmvc 表单字段list提交问题

    比如用户表user 选课表course 用户表有选课字段list<course> courses=new ArrayList<course>(); <input type ...

  3. winform基础,主要控件简单介绍,以及小练习

    WinForm - C/S B/S 客户端应用程序 - 是需要安装在用户电脑上才可以使用的程序特点:不需要联网也可以打开使用部分功能但是现在的情况是许多功能依然需要互联网的支持 代码部分在用户电脑上执 ...

  4. class 文件与dex文件区别 (dvm与jvm区别)及Android DVM介绍

    区别一:dvm执行的是.dex格式文件  jvm执行的是.class文件   android程序编译完之后生产.class文件,然后,dex工具会把.class文件处理成.dex文件,然后把资源文件和 ...

  5. Report&lowbar;矩阵报表的实现(案例)

    2014-05-31 Created By BaoXinjian

  6. 例如找出令人信服的权威C&plus;&plus;中间malloc与new

    例如找出令人信服的权威C++中间malloc与new 问题: 非常多人都知道malloc与new都是用来申请空间用的,开辟空间来源于堆中. 可是在C++中却非常少用malloc去申请空间,为什么? 以 ...

  7. Mac OSX 搭建 Apache php mySql phpMyAdmin 开发环境

    基本环境和配置 Mac 系统:  OS X EI Caption  10.11.4 当前Mac用户名: ceshi 需要熟知的几个基本概念和操作: 1. 新建一个终端默认的是路径是: /Users/当 ...

  8. Linux安装 火速入门

    一.基本简介 Linux是一套免费使用和*传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统. Linux能运行主要的UNIX工具软件.应用程序 ...

  9. Mac Node&period;js 配置

    1.Node.js 简介 Node.js® 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,可方便地构建快速,可扩展的网络应用程序的平台.Node.js 使用事件驱动,非阻塞式 ...

  10. 【2017多校训练08 1002】【HDOJ 6134】Battlestation Operational

    典型的数列反演题. 运用莫比乌斯反演的一个结论 $[n = 1] = \sum_{d | n} \mu(d)$,将表达式做如下转化: $$ ans = \sum_{i=1}^n \sum_{j=1}^ ...