【JVM】初识JVM(上)

平时我们都是用IDE编写好代码后,执行,就能看到效果了。可是我们有没有想过,这其中的流程是怎么样的呢?
我们编写的代码是“java语言”的,可是计算机只能听懂“01语言”。那其中是怎么转换的呢?JVM讲的就是这个。
在这里插入图片描述

引入JVM

java语言到机器语言

我们先来看一个java文件是怎么翻译为机器语言的。
在这里插入图片描述
从上图中可以看出:我们编写出.java文件,经过编译器(javac)编译,生成.class文件,再经过解释器(java)解释,生成机器语言。
JVM起的作用就是:把每一条要执行的字节码交给解释器,翻译成对应的机器码,然后由解释器执行。解释器是JVM的一部分。

记事本验证结论

接下来我们用记事本写个java程序,来验证一下上述结论:
第一步:用记事本写一个简单的方法,保存为.java类型,保存到E盘。
在这里插入图片描述
在这里插入图片描述
第二步:在cmd中执行javac命令,将.java文件编译为.class文件。
在这里插入图片描述
第三步:可以看到,E盘目录下多了一个.class文件。
在这里插入图片描述
第四步:再在cmd中执行java命令,将.class文件解释为机器语言。再经过机器后,程序结果就出来了。
在这里插入图片描述

JVM的概念

定义

一种能够运行java字节码的虚拟机。java字节码是已经经过编译,但与特定机器码无关,需要解释器转译后才能成为机器码的中间码。

和Vmware Workstation是一回事吗?

在这里插入图片描述
两个都叫虚拟机,但两者是不同的。

  • JVM是支持java语言运行的环境,根据不同的操作系统有不同的版本。它之上运行的是java程序,它的作用是能让java程序跨平台运行。
  • Vmware Workstation是VMware公司出的虚拟机,它的作用就是在程序里面模拟操作系统。它之上运行的是操作系统,它的作用是让电脑上多出一个系统来。

为什么要使用JVM?如果没有它,会有哪些不便之处。

在这里插入图片描述
JVM是java能跨平台运行的基础,如果没有JVM,那我们实现一个功能,需要编写N套代码:window版,Linux版等。
JVM有不同的版本,可用来支持不同的操作系统和机器。编译器将.java文件翻译为.class文件,.class文件是通用的。不同的JVM再将.class文件解释成不同的机器语言。

JVM的体系结构

说完了JVM的作用,我们来看看JVM的内部组成,探究一下它是怎么将.class文件解释成机器语言的。

流程

.class文件(字节码文件)被Class Loader加载进运行时数据区,然后执行引擎执行这些字节码。如果需要与异构系统交互,可以通过本地接口进行。
每个线程被创建后,都会产生一个对应的程序计数器和栈,程序计数器中存放的是下一条将要执行的指令,栈中存放的是栈帧,表示的是当前正在执行的方法。当方法在栈中执行完成后,从栈中弹出,栈再进行下一个方法的执行。

各部分解析

上图中的橘色部分是由所有线程共享的数据区,即方法区和堆是所有线程共享的。
白色部分是线程隔离的数据区,即栈、程序计数器是线程私有的。以栈举例,每个线程创建时都会创建自己对应的栈区,里面的数据是私有的,其它栈不能访问。

(1)Class Loader:类加载器

类加载器读取.class文件,将其转换成java.lang.Class类的一个实例,每个实例用来表示一个java类,通过该实例的newInstance()方法可以创建出一个该类的对象。
这一块和反射联系密切。

(2)Execution Engine:执行引擎

用来执行字节码或本地方法。

(3)Native Interface:本地接口

它允许java代码与其它语言(比如C、C++)编写的应用程序和库进行交互。

(4)Runtime Data Area:运行数据区

• 方法区:
其中包含的都是在整个程序中永远唯一的元素,比如class,static变量。

• 堆:
堆是用来存储对象实例以及数组值的区域。java中所有通过new创建的对象的内存都在此分配。堆中的对象的内存需要等待GC进行回收。

• java栈:
栈中只保存基础数据类型(java的8种基本数据类型)和非基本类型的对象的指向堆的地址的引用。

• 本地方法栈:
如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈。

• 程序计数器:
用于存储每个线程下一步将执行的JVM指令,如果该方法为native,则其内部不存储任何信息。

JVM堆分代介绍

堆就是用于类的诞生、成长、消亡的区域。一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。堆分为3代:新生代、老年代、永久代。

三者的联系与区别是:

如果新生代中伊甸区里的空间用完了,程序又需要创建新对象,那就进行如下两步:

  1. JVM的垃圾回收器对其进行垃圾回收,将不再被其他对象所引用的对象进行销毁。
  2. 然后将剩余对象移动到下一区。然后将剩余对象移动到下一区。

值得注意的是:
(1)递增层次为:伊甸区(yi dian)——幸存0区——幸存1区——养老区——永久存储区。
(2)如果养老区也满了,就会产生FullGC,需要对其进行内存清理。否则就会报异常:OutOfMemoryError。
(3)java8中将永久存储区改为了元空间,但说的是一回事。

小结

JVM的体系结构部分还有挺多枝节需要梳理,小编脑容量已不够,待缓缓日后再总结。
至于垃圾回收具体是怎么一回事,请看下篇博客。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡夫卡的熊kfk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值