JVM虚拟机个人总结(一)

来源:互联网 发布:linux编译c文件 编辑:程序博客网 时间:2024/05/16 06:10

千里之堤始于足下,想要学好Java,需要大致了解JVM是如何运行的!
先说一些废话,跟正文无关,不想被唠叨的同学可以直接跳过。不知道大家刚学Java是怎么过来的,我刚学Java的时候,就是老师教我一步一步的走,最后能跑出一个Hello World的一个实例。但是中途为什么这么做,这么做的意义是什么,我一概不知,只是知其然,不知其所以然。我对其内部如何实现的,为何这么实现感到非常好奇,所以在接下来的日子里,我将学习JVM,每周写一次总结,这是我给自己的目标!

好,那么废话不多说,接下来开始正文。首先我需要要确定学习JVM我要了解到什么程度,带着目的的去学习。作为一个已经毕业在开发的人来说,在日常工作中,其实了不了解JVM对于只是码代码的你我没有差别,也就是说你懂或不懂并不影响你实现的工作中的表现。所以如果你甘于这样,那么其实了不了解JVM都无所谓。但是我认为做技术的人,都带有那么一点点不安分的心,不想过像老师等职业一般朝九晚五的生活,所以为了提高技术,那么学习JVM就很有必要了。

那么要了解到什么程度呢?对于我现在刚毕业的小白来讲,我打算了解JVM是如何跑动一个程序的,内部的架构是怎样的等等,但是我个人认为如果我只是想做架构师,而不是底层开发人员,其实JVM你不必了解的太过清晰,只需要在工作上使用的地方了解这么做是怎么实现的就行了。好,接下来进入我对JVM的总结:

首先需要确定Java的体系结构是怎样的?他由什么所组成?
第一:Java的程序设计语言(其实就是在工作中你打的源代码,.java文件中的内容)
第二:Java class文件格式(就是通过javac等编译器编译出的.class文件,是一系列字节码)
第三:Java虚拟机(这个我不就多做介绍了)
第四:Java应用编程接口(就是Java核心API,例如:java.util.*包下的代码等等)

那么Java要运行一个程序需要经历哪些步骤呢?
第一步:用Java编程语言编写源代码
第二步:用Java编译器编译成class文件
第三步:通过Java虚拟机运行class文件
这里写图片描述

Java虚拟机的主要任务是什么?
装载class文件,并且执行其中的字节码。Java虚拟机中包含类加载器,他可以装载Java class文件。Java API只有程序运行需要的那些类才会被加载,字节码由执行引擎来执行。

那么执行引擎又是什么?
不同的Java虚拟机中执行引擎可能会非常的不同。最简单的执行殷勤就是一次性解释字节码,另一种执行引擎更快,但是更加消耗内存,叫做即使编译器。在这种情况下,第一次执行的字节码会被编译成本地字节码,编译出的本地机器代码会被缓存,当方法以后被调用的时候可以重用。第三种执行引擎是自适应优化器。在这种方法下,虚拟机开始的时候解释字节码,但是运行中会监视运行中程序的活动,并且记录下使用频繁的代码段。程序运行的时候,虚拟机只把那些活动最频繁的代码段编译成本地代码,其他不频繁的代码由虚拟机继续解释。

接下来来讲一下Java的自豪点:平台无关性
Java对平台无关性是如何支持的呢?
1.Java平台:Java平台扮演一个Java程序与其下硬件和操作系统之间的缓冲角色,无论Java程序被部署到何处,它只需要与Java平台进行交互,而不需要担心底层的硬件和操作系统。
2.Java语言:保证基本数据类型在所有平台上都一致性(像C或C++语言,基本整数类型int是由它的占位宽度决定的,而它的占位宽度是由它的目标平台决定的)
3.Java class文件:Java class文件可以在任何平台上创建,也可以被任何平台的Java虚拟机装入并运行,与Java虚拟机所在的平台是无关的。

影响Java平台无关性有哪些因素?
1.Java平台的部署(即每个平台都要安装JVM虚拟机)
2.Java平台的版本(需要对应正确的Java版本,比如现在Java 8的新特性,Java 7就没用)
3.本地方法(你的程序是否调用了本地方法,如果是则与平台相关)
4.非标准运行时库(如果调用非标准运行时库,需要知道他是否调用了本地方法)
5.对虚拟机的依赖(在编写程序时,不能依赖程序的及时终结来达到程序的正确性,因为Java并不能确定程序时何时被GC垃圾回收堆回收的。还有不能依赖线程的优先级来达到程序的正确性,因为线程调用的顺序不能明确确定)
6.对用户界面的依赖(下面三点个人觉得不用理解)
7.Java平台实现的bug
8.测试

本星期最后一个总结在于Java的安全性是如何实现的?

Java提供了一个用户可配置的“沙箱”,可以防止不可靠的Java程序。沙箱对不可靠程序的活动进行了限制,程序可以再沙箱的安全边界内做任何事,但是不能进行任何跨越这些边界的举动。版本1.0中的沙箱限制:
1.对本地硬盘的读写操作
2.进行任何网络连接,但不能连接到提供这个applet的源主机
3.创建新的进程
4.装载新的动态连接库

Java沙箱的基本组件是:
1.类装载器结构
2.class文件检查器
3.内置了Java虚拟机的安全特性
4.安全管理器及Java API

这里我只对一、二两点进行解释,个人觉得三、四两点太过于偏向底层,需要用到安全管理器、安全策略等等(至少我是看不懂,感觉帮助也不大)。

那么类装载器体系结构是如何防止恶意代码去干扰善意代码的呢?
这是用过由不同的类装载器装入的类,提供不同的命名空间来实现的。

那么类装载器如何保护可信任的类库?
在有双亲委派模式的情况下,如果网络装载器(个人理解也是系统装载器)装载的某段代码发出指示,需要去下载一个和Java API相同名字的类,比如String类,只使用由他的双亲返回的类,如果没有才能自己在下载。用这种方法,类装载器的体系结构就可以防止他们用自己的版本替换Java中可信任的类了。在允许两个类型之间对包内可见的成员进行访问前,虚拟机不但要确定两个类型属于同一个包,并且还必须确认他们属于同一个运行时包——它们必须是由同一个类装载器装载的。

class 文件检查器是如何进行检查扫描的?
1.第一趟:class文件结构的检查:class文件确认他是否符合Java class文件的基本结构,并且确认class文件没有被删节,尾部没有附带其他字节。主要目的:保证这个字节序列正确地定义了一个新类型,它必须遵从Java class文件的固定格式。
2.第二趟:数据类型的语义检查。检查器查看每个组成部分,比如方法描述符(返回类型、参数的类型和个数、final有没有被子类化)
3.第三趟:字节码的验证
4.第四趟:富豪引用的验证(就是实例引用)

今天的总结就到这,如果发现我总结的不对,请批评指正交流,谢谢!