当前位置: 首页 > 后端技术 > Java

面试官:Java从编译到执行到底发生了什么?

时间:2023-04-01 18:46:58 Java

采访者:今天先从基础开始吧。如何理解Java是一种“跨平台”的语言,即“一次编译,到处运行”?考生:很好理解,因为我们有JVM。考生:Java源代码会被编译成class文件,class文件运行在JVM上。考生:我们在日常开发安装JDK的时候,会发现JDK分为“不同的操作系统”。JDK中包含JVM,所以Java依赖JVM实现“跨平台”候选:JVM是面向操作系统的,负责将Class字节码解释成系统可识别的指令并执行,同时也负责内存程序运行时的管理。面试官:您能谈谈从源代码文件(.java)到代码执行的过程吗?考生:嗯,没问题考生:简单总结一下,我觉得有4个步骤:编译->加载->解释->执行考生:编译:将源代码文件编译成JVM可以解释的class文件。考生:编译过程会对源代码程序进行“句法分析”、“语义分析”、“注释处理”等处理,最终生成字节码文件。考生:比如泛型的擦除,我们经常使用的Lombok,都是在编译阶段完成的。考生:加载:将编译好的class文件加载到JVM中。考生:在loading阶段,可以细化几个步骤:Loading->Connection->Initialization考生:下面对这几个步骤进行详细说明。考生:【加载时机】为了节省内存开销,所有的类并不是一次加载到JVM中,而是只在“需要”的时候才加载(比如new和反射等)考生:【加载发生】的类文件通过“类加载器”加载到jvm中。为了防止同一个字节码在内存中出现多份,使用了双亲委托机制(不会自己去尝试加载这个类,而是将请求委托给父加载器完成,依次向上)考生:【正在加载rules]JDK中的本地方法类一般由根加载器(Bootstrploader)加载,而JDK内部实现的扩展类一般由扩展加载器(ExtClassLoader)加载实现加载,而类文件中的类文件程序由系统加载器(AppClassLoader)加载。候选:Loading这个阶段所做的事情可以概括为:查找并加载类的二进制数据,在JVM“堆”中创建类java.lang.Class的对象,在JVM中存储类相关信息“区”面试官:嗯……考生:通过“加载”这一步,现在class文件已经加载到JVM中,相应的Class对象和类信息也已经创建并存储在方法区。考生:它在“连接”阶段所做的事情可以概括为:验证类信息,为“类变量”分配内存空间,并为其赋默认值。考生:Connection可以细化为几个步骤:Verification->Preparation->Analysis考生:1.Verification:验证类是否符合Java规范和JVM规范,初始化为系统初始值考生:3.分析:符号引用转为直接引用的过程面试官:嗯...考生:通过“连接”这一步,类信息已经验证完毕,分配了内存空间和默认值。考生:接下来就是“初始化”阶段,可以概括为:给类的静态变量赋上正确的初始值。考生:流程大概就是收集类的静态变量、静态代码块、静态方法到()方法,然后从上到下开始执行。候选:如果是“实例化对象”,会调用初始化实例变量的方法,执行相应构造方法中的代码。考生:说了这么多,现在加载阶段(编译->加载->解释->执行)其实已经完成了。下面说一下【解释阶段】做了什么。考生:初始化完成后,当我们试图执行一个类的某个方法时,我们会找到对应方法的字节码信息,然后解释器会将字节码信息解释成系统可以识别的指令代码。考生:在“解释”阶段它所做的事情可以概括为:将字节码转换成操作系统可以识别的指令考生:在解释阶段,将字节码信息解释成机器指令码有两种方式,一种是字节码解释器,一个是即时编译器(JIT)。候选人:JVM会编译“热代码”,直接解释非热代码。当JVM发现某个方法或代码块运行特别频繁时,可以将这部分代码识别为“热点代码”的候选者:使用“热点检测”检测是否为热点代码。“热点检测”一般有计数器和采样两种方法。HotSpot使用“计数器”方法进行检测,为每个方法准备了两类计数器:方法调用计数器和边缘计数器候选:这两种计数器都有一定的阈值,当计数器超过阈值溢出时,就会触发JIT编译.考生:即时编译器将hot方法的命令代码保存下来,下次执行时不需要重复解释,直接执行缓存的机器语言面试官:嗯...考生:经过解释阶段结束,终于到了执行阶段。考生:它在“执行”阶段所做的事情可以概括为:操作系统对解释器解析出的指令代码进行解释,调用系统的硬件来执行最终的程序指令。考生:以上是我对从源代码文件(.java)到代码执行的过程的理解。面试官:嗯……我也想问一下你刚才提到的家长委派模式……应聘者:一定下次!本文总结:Java之所以跨平台,是因为JVM屏蔽了底层操作系统Java的源代码到执行的过程。从JVM的角度来看,可以概括为四个步骤:编译->加载->解释->语法分析后执行“编译”,语义分析和注解处理会在最后生成类文件“加载”,以及步骤可以细分为:加载->连接->初始化。加载加载类文件到JVM,链接验证类信息,分配内存空间并赋默认值,初始化为变量赋正确初值。连接可细分为:验证、准备、分析。“解释”就是将字节码转换成操作系统可识别的可执行指令。JVM中会有一个字节码解释器和一个即时编译器。解释时会分析代码,看是否是“热码”,如果是“热码”,则触发JIT编译,下次执行时无需重复解释,口译速度将得到提高。欢迎关注我的微信公众号【Java3y】聊聊Java面试,在线面试官系列持续更新中!【在线面试官-手机版】系列,每周两篇,持续更新中!【在线面试官-电脑】系列每周两篇持续更新中!原创不易!!一连求三!!