JVM的内存结构(堆,栈,方法区)与编译过程

2 篇文章 0 订阅

JVM的结构(堆,栈,方法区)与编译过程

编译过程

在这里插入图片描述
java文件通过javac的编译成class文件,由于不同的操作系统识别的机器码不同(机器码为0,1组成。汇编语言在不同的系统上面运行需用编写不同的代码来支持汇编语言的运行),在这个方面java使用了jvm虚拟机来实现一处编译四处运行,是通过对应系统的jvm来编译class文件来让不同的操作系统进行识别。

jvm的结构

在这里插入图片描述

程序在执行之前先要把java代码转换成字节码(class文件),jvm首先需要把字节码通过一定的方式 类加载器(ClassLoader,图中为类加载子系统) 把文件加载到内存中 运行时数据区(Runtime Data Area) ,而字节码文件是jvm的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器 执行引擎(Execution Engine) 将字节码翻译成底层系统指令再交由CPU去执行,而这个过程中如需要调用其他语言,这会使用 本地库接口(Native Interface) 来实现整个程序的功能,这就是这4个主要组成部分的职责与功能。

在HotSpot虚拟机中

程序计数器:标记下一段代码需要执行什么,当出现多线程时,每个线程都会独立拥有一个计数器,防止混乱执行

在虚拟机内存中占比较小的内存空间,相当于当前线程所执行的字节码的行号指示器,字节码的解释器工作就是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支丶虚幻丶跳转丶异常处理,线程恢复等基础功能都需要这个计数器完成。并且每个线程都会有一个独立的程序计数器,并且之间互不影响,独立存储,这个类的内存区域为“线程私有”内存。

如果线程执行的是java的方法,那么计数器会记录正在执行的虚拟机字节码地址,如果为Native(其他语言的方法)那么为空。

栈: 每个java方法在执行时,都会创建一个栈帧,所以它的线程是私有制,并且保持着先进后出的特点,同时储存着先进后出的特点,如果保存的内存大于虚拟机允许内存时会出现内存溢出。并且保存着对象的引用以及基本数据类型
在这里插入图片描述
本地方法栈:与栈相比,不同点在于保存的是Native方法,在HotSpot虚拟机中二个栈被合二为一。 在Thread里面 开辟线程时使用的start() 方法会调用一个start0() 将会在本地的操作系统(windows)中执行一个xx.dll(C语言)的文件来在windows系统下开辟一个线程
在这里插入图片描述
堆:作为垃圾回收机制主要管理区域,堆中一般保存的对象,并且作为多线程共享一块内存区域,new出来的对象会首先出现在存在于Eden区,在程序运行时,如果对象没有被回收,对象会被移动到Survivor区,从此一直在Survivor区相互移动(如果对象的数据大于Survivor区的一定内存空间,会被直接移动到老年代),直到当对象头里面的gc分代年龄达到一定数时,会被移动到老年代,当大对象(数据比较大的)会直接出现在老年代具体看垃圾回收机制,可达性算法
在这里插入图片描述

在堆中还分着新生代(复制算法)和老年代(标记清除)分别使用这不同的垃圾回收机制的算法,还有更多分区,其目的都是为了能够更好的回收内存以及分配内存。堆的分配的内存空间在物理上面可以出现不连续,但是需要在逻辑上面出现连续。当然当出现内存无法完成实力分配时同样会出现堆内存溢出

方法区:同样是一块内存共享区域,保存着类的相关信息,常亮以及静态变量和实时编译的代码

在1.8之前这块区域被分配在堆的内存之中,所以还有它还有一个名字为“非堆”,也有人称为“非堆”,为了进行与堆的区分从而将其取得别名,也有名字为“永久代**”,因为保存的数据与堆不一致,在1.8之前这块位置由于内存较小,经常出现内存溢出现象,从而在1.8的时候被分割到本机物理内存中,出现了新的名字为“元空间

运行时的常量池:作为方法区的一部分,比如一个字符串“ab”,不通过堆中开辟空间,并且使用intern()方法,直接以String s =“ab”,当常亮池中有对应的“ab”字符串时,会被保存到常量池中,

直接内存:内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机),这样做的结果就是能够在一定程度上减少垃圾回收对应用程序造成的影响。使用未公开的Unsafe和NIO包下ByteBuffer来创建堆外内存。

1、减少了垃圾回收

使用堆外内存的话,堆外内存是直接受操作系统管理( 而不是虚拟机 )。这样做的结果就是能保持一个较小的堆内内存,以减少垃圾收集对应用的影响。

2、提升复制速度(io效率)

堆内内存由JVM管理,属于“用户态”;而堆外内存由OS管理,属于“内核态”。如果从堆内向磁盘写数据时,数据会被先复制到堆外内存,即内核缓冲区,然后再由OS写入磁盘,使用堆外内存避免了这个操作。

磁盘写数据时,数据会被先复制到堆外内存,即内核缓冲区,然后再由OS写入磁盘,使用堆外内存避免了这个操作。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值