JAVA代码的执行

来源:互联网 发布:java创建一个学生类 编辑:程序博客网 时间:2024/04/28 02:36

JAVA代码的执行分为三个大的步骤

一、代码编译为class文件

根据jvm规范,不同厂商提供了不同的规范。例如在sun jdk中是javac,eclipse用的是jdt

简单分为如下步骤:

1、分析和输入到符号表

2、注解处理

3、语义分析和生产class文件


生成的class文件,不仅仅存放了java的字节码,同时还提供了 结构信息、元数据、方法信息


三、执行class文件

二、装载class文件-classloader

类的加载主要是通过如下的几个过程 装载、连接、初始化,其中初始化可以是提前的静态初始化,或者在方法第一次调用的时候初始化


类的加载主要通过ClassLoader及其子类完成的

分为 Bootstrap Class Loader,Extension Class Loader、System Class Loader、以及User-Defined Class Loader


1、解释执行

在源码编译阶段被编译成jvm的字节码,供解释执行,解释执行特点就是占用内存较少


2、编译执行

分为client compiler(-client)和 server compiler(-server)两种方式

client compiler称为C1是比较轻量级的优化

server compiler称为C2是比较激进的优化

编译执行在运行时进行,通常称为JIT编译器。我们可以通过xint来进行显式的禁用或者启动。因为对执行不频繁的代码采用解释执行的方式,因此sun jdk又称作hotspot vm。


C1的常见优化手段是有方法内联、去虚拟化、冗余消除

方法内联:就是将两个类之间的调用,直接整合成一个类

去虚拟化:就是将接口的唯一实现直接编译了

冗余消除:就是将一些代码根据运行时状况直接删除,例如判定执行的debug,如果运行时不执行,直接将其削除。


C2比较重量级,默认C2在硬件达到2G以上内存,双核的机器上自动安装开启。

C2在C1的基础上又进行了标量替换、栈上分配、同步削除等激进优化手段,运行后C1,C2编译出来的机器码不符合优化条件,会进行逆优化。可以是C2退回到C1,C1退回到解释执行。


3、反射执行

反射耗费性能是因为他要去校验类的权限、方法的权限是否违规,本身在jdk6之后基本上无特别大的性能损耗

将反射的方法cache后和直接调用没啥区别。


总的来说:

1、JIT执行是在程序执行一定的时间之后才能看出调优的效果。

2、解释执行不耗费内存,内存用的较少

3、可以直接指定jdk用C1还是C2进行启动优化