




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Java分布式应用学习笔记02再谈JVM刘岩Emial:suhuanzheng77848771. 前言-为何要再谈JVM很多人认为,分布式Java应用看上去好像和Java虚拟机没什么太多关注的东西,别说分布式系统了,就是一个单机JavaSE系统也不用将JVM学得透透的,有个JVM执行不就行了吗。据笔者的经验回答则是,在大型分布式系统,尤其是云计算服务平台,SAAS也好,PAAS也罢,要求编写的应用必须要高效,你就当你运行的是一个配置很小的机器上,要求资源比较苛刻。所以了解,甚至再学习JVM相关知识还是十分必要的。之前笔者写过一篇关于JVM加载类的文章2. JVM结构JVM主要负责什么工作呢,首
2、先它负责将我们编写的java文件编译成为class文件;第二它负责加载已有的class文件;第三它还负责class的执行;第四JVM还负责内存的分配与回收,这也是为什么大家在写代码的过程中不用手工写代码分配资源和强制回收资源了,有个强势的管家JVM为您做了;JVM还要和底层操作系统接口进行交互完成多线程资源的同步、并发机制,所以为什么我们实现一个Runnable接口或者集成Thread就能完成多线程操作了,表面上看您除了编写一些特殊的类什么都没做,实际上是JVM为您默默做了那么多。Sun,哦,不,笔者老是改不了口,Oracle的Java规范JVM如下:Class文件被类加载器加载,JVM为其开
3、辟内存空间,内存空间又分为四个大部分:方法区、堆区、栈区、本地方法栈区。JVM启动优先级比较小的线程来运行垃圾回收器,时刻监视并回收开辟的内存区域。3. JVM到底如何编译Java代码运行class文件需要将java文件编译成为class文件,JavaSDK如何编译的呢?javac将java源代码编译class过程如下:1:分析输入到符号表:将java文件内容的字符串转变为关键字序列,之后生成一个类似于树状结构的内容,叫做抽象语法树。所谓输入到符号表的意思,就是将类中出现的符号输入类自身的符号表中等。所谓符号一般是指:父类、接口,因为要根据这些符号生成无参构造函数。2:处理注解阶段:在JDK1
4、.5之前,JVM没有这个阶段,但是JDK1.5之后咱们在Java类文件中写的注解需要JVM来进行处理、加强,至于注解保留到何时才生效,具体请参考之后根据抽象语法树中等等信息联系到一起,进行有效性判断,一些列的语义判断,校验,优化某些代码,之后就是我们看到的class文件。class中除了字节码,还包括了JVM执行class的相关信息:结构信息:class的文件格式版本号以及各部分的数量与大小。元数据:元数据代表类的继承关系、接口、声明信息、属性、方法声明信息、常量池信息。方法信息:包括字节码、异常处理表、局部变量区大小我们利用反编译工具反编译一下以前自己写过的class源码,是不是发现确实JD
5、K编译此文件的时候和我们源代码有些许出入,那是它为我们做了优化。4. JVM到底如何执行Java代码JVM执行class文件有3种方式,第一是解释执行、第二是编译执行、第三就是反射执行。可能大家对于第三个反射执行更为熟悉,因为这也是对大家相对真真正正编代码体验过的,而前两者都是由JVM给咱做的,所以听上去就十分陌生。1):解析执行在JVM中解析执行专门执行那些执行频率不高的代码,解析执行内部原理十分类似于咱们学过的汇编语言,JVM用一些自己自定义的指令(汇编语言也有自己一些简单的指令),来完成既有代码的执行过程,说白了,到了最底层,面向对象还是要过程化的。通过4条常用指令完成对类的解析和执行。
6、Invokestatic负责调用static方法,invokevirtual负责调用实例对象方法,invokeinterface对应的是调用接口方法,invokespecial负责private方法的调用以及编译源码后(就是class)生成的构造方法。如下一段代码import java.io.UnsupportedEncodingException;public class UTest public static void main(String args) throws UnsupportedEncodingException String c = .URLDecoder.decode(&q
7、uot;%E4%BA%A7%E5%93%81%E6%8F%8F%E8%BF%B0%E5%9F%9F%E8%B6%8A%E7%95%8C","utf-8");System.out.println(" " + c);编译成class后,使用javap c UTest看字节码内容Compiled from "UTest.java"public class UTest extends java.lang.Objectpublic UTest(); Code: 0: aload_0/装载局部变量第一个值到操作数栈 1: invokes
8、pecial #8; /Method java/lang/Object."<init>":()V/初始化构造器 4: returnpublic static void main(java.lang.String) throws java.io.UnsupportedEncodingException; Code: 0: ldc #19; /String %E4%BA%A7%E5%93%81%E6%8F%8F%E8%BF%B0%E5%9F%9F%E8%B6%8A%E7%95%8C/将字符串值装载到常量池中 2: ldc #21; /String utf-8/将字符
9、串值装载到常量池中 4: invokestatic #23; /Method java/net/URLDecoder.decode:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;/调用静态方法.URLDecoder.decode 7: astore_1/将操作数栈中栈顶的值弹出放入局部变量区 8: getstatic #29; /Field java/lang/System.out:Ljava/io/PrintStream; 11: new #35; /class java/lang/StringBuilder 14: dup
10、15: ldc #37; /String 17:invokespecial #39; /Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 20: aload_1 21:invokevirtual #42; /Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24:invokevirtual #46; /Method java/lang/StringBuilder.toStr
11、ing:()Ljava/lang/String; 27:invokevirtual #50;/Method java/io/PrintStream.println:(Ljava/lang/String;)V 30: return估计大家都看烦了,习惯了面向对象思维的大家一看这种汇编似的语言确实头疼,耐不下心。如果不是搞JVM开发的,其实了解一下就可以,毕竟了解一下JVM运行原理,对于我们写代码,无异于又过了一层思考。解释执行比较慢,但是呢,比较省资源,省内存,因为采用栈这种数据结构进行指令的收编和采集,运用,空间利用率可见是比较节俭的。2):编译执行:为了提升性能,JDK还可以编译执行,也叫做
12、即时编译器,通常是对执行频率比较高的代码进行及时编译执行。编译执行牺牲了部分空间资源,换来的是优化了字节码的编译实际代码块,就是说我们编写的代码在JVM编译器看来是可优化的,所以它采用优化编译,将原先的代码进行一些调整,进而更好地利用JVM资源。编译执行那个主要分为2类,一个是客户端类型,属轻量级;一类是服务端类型,属于重量级。客户端执行的优化策略有如下3种措施方法内联:一个方法的执行离不开其他方法的支持,若调用的其他方法十分简单。那么调用的时候会将被调用那个方法里面所有的内容粘到主调方法中,这样做的好处是节省参数变量,中间变量的资源和返回值的资源申请位置。private void test(
13、)test2("1");private String test2(String a)/test2的方法体return null;在JVM编译中会变成如下方式private void test()/test2的方法体去虚化处理:装载类的时候会进行类层次的分析,如果发现接口的方法是有一个实现类,那么JVM会说,别故弄玄虚了,就那么一个实现类,咱将实现类的方法实现内容全粘过来才是实在人,做人要厚道。接口如下public interface IA public void t();实现类如下public class A implements IA public void t()/做你
14、想做的事情下面是一个客户端调用类class Demopublic void execute(IA ia)ia.t();那么JVM去虚化会将此代码替换成class Demopublic void execute(IA ia)/做你想做的事情冗余消除:冗余消除是在编译期间发现代码可以进行折叠或者消除。比如如下代码public class A implements IA final static boolean isDebug = false;public void t()if(isDebug)System.out.println("容我三思");System.out.print
15、ln("全线出击");反编译后的class内容如下import java.io.PrintStream;public class A implements IA static final boolean isDebug = false; public void t() System.out.println("全线出击"); 编译期间可以确定代码不会执行到“容我三思”的步骤,您只能“全线出击”。服务器模式编译则比客户端模式编译更加费资源,因为编译器模式的很多优化策略是从整体类运行出发的,主要优化点是标量替换、栈上分配、同步消除三项。这三项优化措施都是基于分
16、析变量是否逃逸的分析结果。这些我们知道有这么个事情,了解一下即可,因为咱们还没到开发JVM的程度。3):反射执行:先回顾一下反射的代码,再来看看JVM如何处理反射执行的过程的Class cls = Class.forName("java.lang.String");Object obj = cls.newInstance();Method method = cls.getMethod("valueOf", Object.class);String str = (String) method.invoke(obj, 1);System.out.printl
17、n(str);反射调用实际就是动态生成字节码,并加载到JVM中进行执行。流程如下:先让调用者所在的ClassLoader来加载创建Class对象,Class对象生出来了,之后校验Class是否为public权限的,如果不是,那么对不起,反射机制在伟大也不能违反原则,越雷池一步,不是public的类,您还是少碰为妙!之后JVM调用对象的newInstance方法,该方法先去查找是否有缓存的ConstructorAccessor对象,如果没有则生成一个。生成ConstructorAccessor的过程需要MethodAccessorGenerator中的generate方法根据Class格式规范生成字节码,在生成字节码后
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025届四川省遂宁市高中高考冲刺押题(最后一卷)化学试卷含解析
- 2025届山东省临沂市蒙阴县实验中学高三第二次联考化学试卷含解析
- 宁夏石嘴山市三中2025届高考化学一模试卷含解析
- 2025年记忆绵家居制品项目发展计划
- 人教版四年级下册数学期中测试基础达标卷(含答案)
- 护理插管操作规程
- 2025年镍镉电池项目合作计划书
- 中考数学高频考点专项练习:专题15 圆综合训练及答案
- 2025年吡唑啉酮合作协议书
- 幼儿小班安全不退椅子
- 学生作业打卡模板
- 水文资料在线整编规范
- DZ∕T 0222-2006 地质灾害防治工程监理规范(正式版)
- 2024届高考语言运用之比较赏析句子的表达效果+
- 施工现场动火作业安全(旁站记录)
- 工程变更通知单ECN模板-20220213
- 2024武汉六校联考高一(下)期中数学试卷及解析
- 课本剧哈姆雷特剧本
- 安宁护理个案
- 硬笔字灵飞经临写
- 命案防控知识讲座
评论
0/150
提交评论