做柱状图饼状图好看的网站,深圳微信商城网站设计价格,如何做拍卖网站,清远新闻最新1、JVM 简介JVM 是我们Javaer 的最基本功底了#xff0c;刚开始学Java 的时候#xff0c;一般都是从“Hello World ”开始的#xff0c;然后会写个复杂点class #xff0c;然后再找一些开源框架#xff0c;比如Spring #xff0c;Hibernate 等等#xff0c;再然后就开发…1、JVM 简介JVM 是我们Javaer 的最基本功底了刚开始学Java 的时候一般都是从“Hello World ”开始的然后会写个复杂点class 然后再找一些开源框架比如Spring Hibernate 等等再然后就开发企业级的应用比如网站、企业内部应用、实时交易系统等等直到某一天突然发现做的系统咋就这么慢呢而且时不时还来个内存溢出什么的今天是交易系统报了StackOverflowError 明天是网站系统报了个OutOfMemoryError 这种错误又很难重现只有分析Javacore 和dump 文件运气好点还能分析出个结果运行遭的点就直接去庙里烧香吧每天接客户的电话都是战战兢兢的生怕再出什么幺蛾子了。我想Java 做的久一点的都有这样的经历那这些问题的最终根结是在哪呢—— JVM 。JVM 全称是Java Virtual Machine Java 虚拟机也就是在计算机上再虚拟一个计算机这和我们使用 VMWare不一样那个虚拟的东西你是可以看到的这个JVM 你是看不到的它存在内存中。我们知道计算机的基本构成是运算器、控制器、存储器、输入和输出设备那这个JVM 也是有这成套的元素运算器是当然是交给硬件CPU 还处理了只是为了适应“一次编译随处运行”的情况需要做一个翻译动作于是就用了JVM 自己的命令集这与汇编的命令集有点类似每一种汇编命令集针对一个系列的CPU 比如8086 系列的汇编也是可以用在8088 上的但是就不能跑在8051 上而JVM 的命令集则是可以到处运行的因为JVM 做了翻译根据不同的CPU 翻译成不同的机器语言。JVM 中我们最需要深入理解的就是它的存储部分存储硬盘NO NO JVM 是一个内存中的虚拟机那它的存储就是内存了我们写的所有类、常量、变量、方法都在内存中这决定着我们程序运行的是否健壮、是否高效接下来的部分就是重点介绍之。2、JVM 的组成部分我们先把JVM 这个虚拟机画出来如下图所示从这个图中可以看到JVM 是运行在操作系统之上的它与硬件没有直接的交互。我们再来看下JVM 有哪些组成部分如下图所示该图参考了网上广为流传的JVM 构成图大家看这个图整个JVM 分为四部分## Class Loader 类加载器类加载器的作用是加载类文件到内存比如编写一个HelloWord.java 程序然后通过javac 编译成class 文件那怎么才能加载到内存中被执行呢Class Loader 承担的就是这个责任那不可能随便建立一个.class 文件就能被加载的Class Loader 加载的class 文件是有格式要求在《JVM Specification 》中式这样定义Class 文件的结构ClassFile {u4 magic;u2 minor_version;u2 major_version;u2 constant_pool_count;cp_info constant_pool[constant_pool_count-1];u2 access_flags;u2 this_class;u2 super_class;u2 interfaces_count;u2 interfaces[interfaces_count];u2 fields_count;field_info fields[fields_count];u2 methods_count;method_info methods[methods_count];u2 attributes_count;attribute_info attributes[attributes_count];}需要详细了解的话可以仔细阅读《JVM Specification 》的第四章“The class File Format ”这里不再详细说明。友情提示Class Loader 只管加载只要符合文件结构就加载至于说能不能运行则不是它负责的那是由Execution Engine 负责的。## Execution Engine 执行引擎执行引擎也叫做解释器(Interpreter) 负责解释命令提交操作系统执行。## Native Interface 本地接口本地接口的作用是融合不同的编程语言为Java 所用它的初衷是融合C/C 程序Java 诞生的时候是C/C 横行的时候要想立足必须有一个聪明的、睿智的调用C/C 程序于是就在内存中专门开辟了一块区域处理标记为native 的代码它的具体做法是Native Method Stack 中登记native 方法在Execution Engine 执行时加载native libraies 。目前该方法使用的是越来越少了除非是与硬件有关的应用比如通过Java 程序驱动打印机或者Java 系统管理生产设备在企业级应用中已经比较少见因为现在的异构领域间的通信很发达比如可以使用Socket 通信也可以使用Web Service 等等不多做介绍。## Runtime data area 运行数据区运行数据区是整个JVM 的重点。我们所有写的程序都被加载到这里之后才开始运行Java 生态系统如此的繁荣得益于该区域的优良自治。整个JVM 框架由加载器加载文件然后执行器在内存中处理数据需要与异构系统交互是可以通过本地接口进行瞧一个完整的系统诞生了3、JVM加载class文件的原理机制Java中的所有类都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类而它的工作就是把class文件从硬盘读取到内存中。在写程序的时候我们几乎不需要关心类的加载因为这些都是隐式装载的除非我们有特殊的用法像是反射就需要显式的加载所需要的类。类装载方式有两种1.隐式装载 程序在运行过程中当碰到通过new 等方式生成对象时隐式调用类装载器加载对应的类到jvm中2.显式装载 通过class.forname()等方法显式加载需要的类隐式加载与显式加载的区别两者本质是一样?Java类的加载是动态的它并不会一次性将所有类全部加载后再运行而是保证程序运行的基础类(像是基类)完全加载到jvm中至于其他类则在需要的时候才加载。这当然就是为了节省内存开销。Java的类加载器有三个对应Java的三种类:(java中的类大致分为三种 1.系统类 2.扩展类 3.由程序员自定义的类 )Bootstrap Loader // 负责加载系统类 (指的是内置类像是String对应于C#中的System类和C/C标准库中的类)|- - ExtClassLoader // 负责加载扩展类(就是继承类和实现类)|- - AppClassLoader // 负责加载应用类(程序员自定义的类)三个加载器各自完成自己的工作但它们是如何协调工作呢哪一个类该由哪个类加载器完成呢为了解决这个问题Java采用了委托模型机制。委托模型机制的工作原理很简单当类加载器需要加载类的时候先请示其Parent(即上一层加载器)在其搜索路径载入如果找不到才在自己的搜索路径搜索该类。这样的顺序其实就是加载器层次上自顶而下的搜索因为加载器必须保证基础类的加载。之所以是这种机制还有一个安全上的考虑如果某人将一个恶意的基础类加载到jvm委托模型机制会搜索其父类加载器显然是不可能找到的自然就不会将该类加载进来。我们可以通过这样的代码来获取类加载器:ClassLoader loader ClassName.class.getClassLoader();ClassLoader ParentLoader loader.getParent();注意一个很重要的问题就是Java在逻辑上并不存在BootstrapKLoader的实体因为它是用C编写的所以打印其内容将会得到null。前面是对类加载器的简单介绍它的原理机制非常简单就是下面几个步骤:1.装载:查找和导入class文件;2.连接:(1)检查:检查载入的class文件数据的正确性;(2)准备:为类的静态变量分配存储空间;(3)解析:将符号引用转换成直接引用(这一步是可选的)3.初始化:初始化静态变量静态代码块。这样的过程在程序调用类的静态成员的时候开始执行所以静态方法main()才会成为一般程序的入口方法。类的构造器也会引发该动作。