首页 > 其他 > 详细

JVM内存分配

时间:2020-07-16 23:17:34      阅读:51      评论:0      收藏:0      [点我收藏+]

内存布局

JVM内存大概分为几块区域:堆、栈、程序计数器、MetaSpace元空间、直接内存区,见下图

技术分享图片

线程级内存区域:栈、程序计数器,堆与操作系统一样多个线程共享。

本地方法栈

本地方法栈是和虚拟机栈非常相似的一个区域,它服务的对象是 native 方法。你甚至可以认为虚拟机栈和本地方法栈是同一个区域

Java虚拟机栈

Java虚拟机栈中存放的是栈帧(Frame),而运行的每个方法都会产生一个栈帧,最后执行的方法栈帧在栈顶,所以是FILO。一个栈帧中包含:

  1. 局部变量表: 存放局部变量的引用
  2. 动态链接:
  3. 操作数栈:执行字节码的地方,类比操作系统的栈执行过程。
  4. 返回地址:只存在于字节码层面,对于 JVM 来说,程序就是存储在方法区的字节码指令,而 returnAddress 类型的值就是指向特定指令内存地址的指针

程序计数器

线程级别内存,程序计数器存储了当前正在运行的流程,包括正在执行的指令、跳转、分支、循环、异常处理等,简单理解为记录当前线程执行字节码的行号的区域。

堆是 JVM 上最大的内存区域 ,多线程共享区域,我们经常说一个变量是非线程安全的,那这个变量一定就存放在堆里面, 堆也是GC的重点对象。
一个对象创建的时候,到底是在堆上分配,还是在栈上分配呢?这和两个方面有关:对象的类型和在 Java 类中存在的位置。Java 的对象可以分为基本数据类型和普通对象

  • 对于普通对象来说,JVM 会首先在堆上创建对象,然后在其他地方使用的其实是它的引用。比如,把这个引用保存在虚拟机栈的局部变量表中。
  • 对于基本数据类型来说(byte、short、int、long、float、double、char),有两种情况。

当在方法体内声明了基本数据类型的对象,它就会在栈上直接分配。其他情况,都是在堆上分配。
像 int[] 数组这样的内容,是在堆上分配的。数组并不是基本数据类型

元空间

存放类的信息、常量池、方法数据、方法代码等,元空间属于堆外内存,-XX:MaxMetaspaceSize 来控制大小。这里解释下:方法区是JVM规范中的一个逻辑概念,在Java8之前叫永久代(Perm Area) , 可以理解为 Java8 之前方法区的实现是永久代,Java8 之后是元空间。

常量池

  • 字符串常量池:java8在堆中,java8之前是perm区。虽然java8之前perm也属于堆区,但是此堆非彼堆。
  • 类文件常量池:metaspace区
  • 运行时常量池:metaspace区

JVM内存分配

原文:https://www.cnblogs.com/lihuamaoa/p/13291220.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!