欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JVM内存管理(内存分配和内存溢出异常)

程序员文章站 2022-04-15 17:46:45
JVM之内存管理前言运行时数据区前言上篇对JVM做了一个入门级的了解,之后的学习大部分都是根据JVM的体系结构细化出来学习的,在复习一下JVM体系结构看下图,今天总结一下java虚拟机的内存的各个区域,跟我一起了解虚拟机是怎样使用内存的,如何排查错误,让我们一起走JVM体系结构中的运行时数据区(内存区)运行时数据区Java虚拟机在执行Java程序 的过程中会把它管理的所有内存划分为若干个不同数据区域橙色是由线程共享的区域,随着虚拟机的启动一直存在蓝色则依赖用户线程的启动和结束而建立和销毁...



前言

JVM内存管理(内存分配和内存溢出异常)

上篇对JVM做了一个入门级的了解,之后的学习大部分都是根据JVM的体系结构细化出来学习的,在复习一下JVM体系结构看下图,今天总结一下java虚拟机的内存的各个区域,跟我一起了解虚拟机是怎样使用内存的,如何排查错误,让我们一起走JVM体系结构中的运行时数据区(内存区)
JVM内存管理(内存分配和内存溢出异常)

运行时数据区

JVM内存管理(内存分配和内存溢出异常)

Java虚拟机在执行Java程序 的过程中会把它管理的所有内存划分为若干个不同数据区域

  • 橙色是由线程共享的区域,随着虚拟机的启动一直存在(线程私有)
  • 蓝色则依赖用户线程的启动和结束而建立和销毁(线程隔离的数据区,线程共享)

程序技术器

可以看做是当前线程所执行的字节码的行号指示器,JVM工作时,就是通过改变这个计时器来选取下一条需要执行的字节码指令

Java虚拟机栈

虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,虚拟机会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等.
JVM内存管理(内存分配和内存溢出异常)

局部变量表: 存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、
、short、int、float、long、double),类型引用和returnAddress类型,局部变量表的内存空间在编译期间完成分配,方法在帧分配多少内存固定

本地方法栈

与虚拟机栈非常相似,区别是虚拟机栈执为虚拟机执行Java方法,而本地方法栈是为虚拟机使用到本地(Native)方法服务

Java堆

虚拟内存最大的一块,存放对象实例

方法区

存储已被虚拟机加载的类型信息,常量,静态变量,即使编译器编译后的代码缓存.
运行时常量池,也是方法区的一部分,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中

内存分配

介绍完java虚拟机的运行时数据区,大致知道了内存结构都有什么,了解了内存中放什么,那么它们是如何创建的,如何布局的及如何访问的.

对象的创建

创建兑现通常仅仅一个new关键字而已,而在虚拟机中,对象的创建时什么过程呢?
1.Java虚拟机遇到一个new字节码,首先检查这个指定的参数是否能再常量池中中定位到
2.检查这个符号引用代表的类是否被加载,解析和初始化,如果没有那必须执行类加载过程
3.类加载检查通过后,为新生对象分配内存

  • 指针碰撞
    从java堆中划分一块大小确定的内存,如果内存规整的,所有被使用的放在一边未被使用过的放在另一边,中间放着一个指针作为分界点的指示器,内存分配多少,指针像空闲方向就挪动多少
  • 空闲列表
    内存如果不是规整的,内存和空闲区相互交错在一起,那么使用空闲列表,用空闲列表记录剩余可用的内存空间,每次为变量分配内存后动态维护这个列表

JVM内存管理(内存分配和内存溢出异常)

对象内存布局

对象在堆内存中的存储布局可以划分为三个部分:对象头,实例数据和对齐填充
对象头包括两个部分:
1.用于存储对象自身的运行时数据,如哈希码,GC分带年龄,锁状态标志,线程持有的锁
2.对象的另一部分是类型指针,java虚拟机通过这个指针来确定该对象是哪个类的实例
实例数据: 真正存储有效信息,程序代码里定义的各种类型的字段内容
对齐填充: 没有特别意义,仅仅是占位符,HotSpot内存管理要求任何对象大小必须是8的倍数

对象的访问定位

对象有了,怎么去使用它呢?两种方式,句柄和直接指针,一般说两个东西的时候都会做对比优缺点,那么来比较比较它们两个
使用句柄: 如果使用句柄,java堆会划分出一块内存来作为句柄池,句柄中包含了实例数据与类型数据格子具体地址,看下图
JVM内存管理(内存分配和内存溢出异常)
优点:reference中存储稳定句柄,在对象移动时改变实例数据指针即可
使用直接指针:
reference直接就是对象地址,如果访问对象本身不需要多一次间接访问开销(和上图比少实例池)
JVM内存管理(内存分配和内存溢出异常)
优点:速度更快

内存溢出异常(OOM)

除了程序计数器外,虚拟机的其他几个运行时区域都会发生OOM异常,那么我们怎么排除是哪里出错了呢
JVM内存管理(内存分配和内存溢出异常)

总结

最后我们明白了虚拟机里边的内存结构与划分,如果内存溢出了可以快速定位到哪个结构什么原因溢出了,帮助我们可以快速解决问题.

本文地址:https://blog.csdn.net/a15076159739/article/details/108233132