首页 > 其他 > 详细

一篇看懂JVM底层详解,利用class反编译文件了解文件执行流程

时间:2021-03-12 12:29:35      阅读:20      评论:0      收藏:0      [点我收藏+]

JVM之内存结构详解

 

JVM内存结构

java虚拟机在执行程序的过程中会将内存划分为不同的区域,具体如图1-1所示.

五个区域

JVM分为五个区域:堆、虚拟机栈、本地方法栈、方法区(元空间)、程序计数器

PS: 1.五个区域中,虚拟机栈、本地方法栈、程序计数器为线程私有、方法区和堆为线程共享区; 2.JVM中不同区域的占用大小不同,堆最大,程序计数器最小,Java中最多的“对象”就是放在堆中

堆得主要作用就是存储对象,它占用最大的内存空间堆区,也同样成为了java垃圾收集器的重要对象。因此也被称为“GC堆”。堆是jvm所有线程共有的。

技术分享图片

图1-1-1

由于垃圾收集器GC采用分代收集算法,所以堆内存中也分成了 2/3年轻代,1/3老年代 。如图1-1-1所示。

关于JAVA垃圾收集器GC分代的概念:

JVM 内置的通用垃圾回收原则,堆内存划分为 Eden、Survivor 和 Tenured/Old 空间bai。GC一共分三种:MinorGC,Major GC v和Full GC。Full GC是清理整个堆空间—包括年轻代和永久代。有时候系统会频繁的FullGC,这时候需要去服务器查一下原因。

新生成的对象首先放到年轻代Eden区,当Eden空间满了,触发Minor GC,存活下来的对象移动到Survivor0区,Survivor0区满后触发执行Minor GC,Survivor0区存活对象移动到Suvivor1区,这样保证了一段时间内总有一个survivor区为空。经过多次Minor GC仍然存活的对象移动到老年代。老年代存储长期存活的对象,占满时会触发Major GC=Full GC,GC期间会停止所有线程等待GC完成,所以对响应要求高的应用尽量减少发生Major GC,避免响应超时。 Minor GC : 清理年轻代 Major GC : 清理老年代 Full GC : 清理整个堆空间,包括年轻代和永久代 所有GC都会停止应用所有线程。

关于新生代到老年代的规则:

如图1-1-2所示:

1.minorgc回收整个年轻带,挪一次分代年龄+1,长期存活的对象分代年龄达到15到老年代。或者survior满了会触发minorGC会自动到达老年代。

2.一批对象如果大于surviovr区域百分之五十直接进入老年代

3.为了避免大对象分分配内存是需要复制大对象会直接进入老年代

 

图1-1-2

JVMGC内部采用可达性分析算法回收对象,具体规则如图1-1-3所示,可达性算法是将“GC Roots”作为起点,搜索引用的对象,搜索到的对象打上标记。未搜索的标记为非垃圾对象。

 

图1-1-3

 

Java虚拟机栈

虚拟机栈中存储的是方法,栈中的数据都是以栈帧的格式存在,我们简称栈帧,栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构。java虚拟机栈是线程私有的,它的生命周期是和线程一样。每个线程在创建的时候都会创建一个虚拟机栈。但是而在栈帧中分为操作数栈,局部变量,动态链接,返回地址等。

ps:1.每一个栈帧遵循先进后出后进先出的出栈入栈规则。

2.操作数栈:从局部变量中或者对象实例中复制常量或者变量到操作数栈,在随着计算将栈中元素出栈到局部变量或者返给方法调用者。通俗来说,就是传递参数的。

3.动态链接,每一个栈帧都会有一个指向运行时常量池(运行时常量池是在JVm在运行加载类的时候,把class文件里的常量放到运行时常量里。一个类对应一个运行时常量池)的引用,来支持方法与方法之间的调用。字节码中的方法调用指令就以常量池中方法的符号引用为参数。

4.局部变量中的对象指针指向堆

本地方法栈

首先,什么是本地方法呢?JVM中的本地方法是指java带有修饰符native的方法,但是方法体不是用java写的。这一类方法被称为java本地方法。这类方法的存在的意义是为了弥补java代码不方便实现的缺陷而提出的。

本地方法栈,作用与java虚拟机栈类似。 区别是:虚拟机栈为虚拟机执行java方法服务,而本地方法是为native方法服务。

本地方法栈是线程私有的。它的生命周期与线程相同,每个线程只有一个。

方法区(元空间)

1.线程共享。在虚拟机启动时候创建,所有jvm线程共享。

2.上文所提到的运行时常量池就是方法区的一部分。

3.被装载的class文件的信息存储在方法区中的运行时常量池中,他使用类装载器定义相应的class文件

4.用于存在已被虚拟机加载的类信息,常量,变量,静态变量

程序员写的代码其实在在jvm虚拟机中被转成了一条条指令集执行的。如下图。

技术分享图片图5-1

程序计数器

程序计数器也叫PC寄存器,是一块内存空间,如果将class文件进行反编译后,就能看到一条条的指令集,如图5-1动图所示,PC代表的就是程序计数器的计数。

他可以看作是线程所执行的字节码的行号指示器,在虚拟机中,字节码解释器工作时,就是根据程序计数器的值来选取下一条需要执行的指令。分支、循环、异常处理、跳转都是需要这个程序计数器来完成。当虚拟机正在执行一个本地方法也就是native方法时,程序计数器存储的值是undefined。程序计数器是私有的。它的生命周期与线程相同,每个线程都有一个。

JAVA程序执行顺序:

1.加载主方法的class文件进入方法区,方法区加载类的信息。

2.执行程序后,方法区的方法入栈,栈给方法分配栈帧。

3.遇到new对象的情况就在堆中开辟这个类的实例空间

arthas:查看cpu,jvm调优工具

JVMGC垃圾收集器:在底层执行的时候,会停掉所有线程(stop the world 简称STW),尽量的减少full gc.

面试:1.为什么要设计STW?

      2.能否对jVM调优,让其几乎不发生Full  Gc

 



一篇看懂JVM底层详解,利用class反编译文件了解文件执行流程

原文:https://www.cnblogs.com/hglh/p/14522572.html

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