谈谈 Java Virtual Machine 以及 GC

JVM(Java Virtual Machine),Java 虚拟机,它是一种标准,通过这种标准它不需要依赖硬件,通过 jvm 虚拟的硬件操作实现“一次编译,多次运行”。

JVM 总共分为五个模块,分别是:类装载器子系统、运行时数据区、执行引擎、本地方法接口和垃圾收集模块

大家可以看看下面这个图,把重点的部分都已经呈现出来了。

类装载子系统:

 负责将字节码文件加载到运行时数据区中,完成程序的装载功能

字节码执行引擎:

根据运行平台环境不同,对字节码指令进行翻译,让硬件去做相应的工作

堆:

堆主要是用来存储在程序运行过程种产生的对象信息,当然,它自身也有非常复杂的结构,后面提到的GC也是和它密切相关的

栈:

栈,又称线程栈,当执行 main 函数时候,就会生成一个 main 线程栈帧,同时将这个线程入栈到当前线程栈中,当发生函数调用时候,会对新的方法生成一块栈帧结构,入栈到当前线程栈中。

栈帧内部也是有很复杂的数据结构,其中最重要的 4 块内容已经在图上标注出来了。

局部变量表:

用来存放函数局部变量的

操作数栈:

用来存放当前正在使用的数据,是以栈的结构组织存储的

动态链接:

程序中会存在大量的地址引用,但是程序中的地址引用都是逻辑地址引用,并不是物理内存地址引用,动态链接的作用就是实现逻辑地址到物理地址的变换工作

方法出口:

当函数调用执行完毕后,需要回到调用程序段继续程序的运行,所以需要方法出口来进行记录

本地方法栈:

在 Java 诞生的时候还是 C 语言的天下,当时的 JVM 是由 C 语言编写的,所以需要使用 java 去调用 c 语言的类库,这就称为本地方法。所以本地方法栈就是用来存储调用本地方法所产生的临时信息

方法区:

方法区,在JDK1.8以后被改名为元空间,主要就是存储类元信息,常量,静态变量,方法等等

通过 new 字段生成的对象都是对这个区域类元信息的引用

程序计数器:

程序计数器,就是用来表明程序当前运行到那里的位置信息,程序运行无非就三种结构:顺序、循环、选择,但是无论是什么方式都需要通过一个标识来一行一行的运行程序,这个标识就是程序计数器

GC

 Java 垃圾回收机制,主要回收的区域就是

堆主要分为两大块:年轻代和老年代。每 new 一个对象都被放在 Eden 区,如果 Eden 满的话会触发一次 minor GC 操作,将 Eden 中无引用的对象回收掉,将剩下的对象剪切到 from 区域,如果再一次 Eden 区域满的话,会将 Eden 区域和 from 区域都进行回收,将剩下的对象放入 to 区域。每个对象头部都有一条分代年龄字段,初始为 0,最大为 15 ,没进行一次 minor GC后,幸存下来的对象分代年龄字段会加一,当分代年龄为 15 时,GC就会认为这个对应老了,不能够再年龄代中活跃了,将他放到老年代区域中。但是总有一个时候老年代区域也会被放满吧?当老年代被放满的时候系统就会触发一次 full GC,注意执行这个 GC 操作后系统将停止运行,专门用来垃圾回收。

所以 JVM 调优首先要做的就是合理分配他们的内存大小,减少其 full GC 执行的频率。另外就是调整 GC 算法,这个就是更深层次的问题了,想要了解 GC 算法小伙伴自行下去百度~

发布了39 篇原创文章 · 获赞 20 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/cong____cong/article/details/102882512
今日推荐