极客时间杨晓峰JAVA36讲内容总结与扩展(一)

谈谈你对java平台的理解,"java是解释执行的",这句话正确吗?

java本身是一种面向对象的编程语言,最显著的两个特性:

1.write once,run anywhere    一次书写,到处运行

2.GC,Garbage Collection    垃圾收集

日常开发中我们用的JRE与JDK的区别:

jre : Java运行环境,包含了JVM和java类库,以及一些模块

jdk : 可以看做是jre的一个超集,提供了跟多的工具,比如编译器/各种诊断工具

而对于"java是解释执行的"这句话说法不太准确.文章中是这样说:

开发的java源代码---->javac编译成字节码(bytecode)------>JVM内嵌的解释器将字节码转换为机器码.但是常见的JVM大多数使用的是Orcal JDK提供Hotspot JVM,提供了JIT编译器,也就是动态编译器,JIT能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就是属于编译执行,而不是解释执行了.

对于java平台的理解,可以从很多方面简明扼要的说一下,如:

1.java语言特性 : 泛型/lambda等语言特性

2.基础类库 : IO/NIO 网络 并发 安全等

或者说下JVM的概念与机制,如:

类加载机制

    1.常用jdk内嵌的class-loder,例如:bootstrop/application和extension class-loder

    2.类加载过程:加载-->验证-->连接-->初始化

垃圾收集器

    1.serialGC

    2.ParallelGC

    3.CMS

    4.G1

3.自定义class-loder

还有一些JDK自带的的诊断与监控工具等,下图是一个相对宽泛的蓝图:

0cba34247efaf8038262f277847aa31cc1c.jpg

我们通常把java分为编译期和运行时。javac将java源码编译成".class"文件,而不是直接编译成能执行的机器码。java通过字节码和JVM这种跨平台的抽象,屏蔽了操作系统和硬件的细节,这也是实现“一次编译,到处执行”的基础。

jvm在启动时,可以指定不同的参数对运行模式进行选择。如:

-Xint:告诉JVM只进行解释执行,不对代码进行编译,这种模式抛弃了JIT可能带来的性能优势。

-Xcomp:告诉jvm关闭解释器。不需要进行解释执行,或者叫最大优化级别。这种模式是否会更高效?不一定。这个参数会导致JVM启动变慢,同时有些JIT编译器优化方式,如果不进行profiling往往不能进行有效优化。

JVM作为一个强大平台,不仅仅只要java语言在jvm上运行,如Scala,Groovy等。

评论部分:
Woj评论:
“一次编译、到处运行”说的是Java语言跨平台的特性,Java的跨平台特性与Java虚拟机的存在密不可分,可在不同的环境中运行。比如说Windows平台和Linux平台都有相应的JDK,安装好JDK后也就有了Java语言的运行环境。其实Java语言本身与其他的编程语言没有特别大的差异,并不是说Java语言可以跨平台,而是在不同的平台都有可以让Java语言运行的环境而已,所以才有了Java一次编译,到处运行这样的效果。
        严格的讲,跨平台的语言不止Java一种,但Java是较为成熟的一种。“一次编译,到处运行”这种效果跟编译器有关。编程语言的处理需要编译器和解释器。Java虚拟机和DOS类似,相当于一个供程序运行的平台。
        程序从源代码到运行的三个阶段:编码——编译——运行——调试。Java在编译阶段则体现了跨平台的特点。编译过程大概是这样的:首先是将Java源代码转化成.CLASS文件字节码,这是第一次编译。.class文件就是可以到处运行的文件。然后Java字节码会被转化为目标机器代码,这是是由JVM来执行的,即Java的第二次编译。
        “到处运行”的关键和前提就是JVM。因为在第二次编译中JVM起着关键作用。在可以运行Java虚拟机的地方都内含着一个JVM操作系统。从而使JAVA提供了各种不同平台上的虚拟机制,因此实现了“到处运行”的效果。需要强调的一点是,java并不是编译机制,而是解释机制。Java字节码的设计充分考虑了JIT这一即时编译方式,可以将字节码直接转化成高性能的本地机器码,这同样是虚拟机的一个构成部分。 

magict4评论:
我对『Compile once, run anywhere』这个宣传语提出的历史背景非常感兴趣。这个宣传语似乎在暗示 C 语言有一个缺点:对于每一个不同的平台,源代码都要被编译一次。我不解的地方是,为什么这会是一个问题?不同的平台,可执行的机器码必然是不一样的。源代码自然需要依据不同的平台分别被编译。 我觉得真正问题不在编译这一块,而是在 C 语言源文件这一块。我没有 C 语言的编程经验,但是似乎 C 语言程序经常需要调用操作系统层面的 API。不同的操作系统,API 一般不同。为了支持多平台,C 语言程序的源文件需要根据不同平台修改多次。这应该是一个非常大的痛点。我回头查了一下当时的宣传语,原文是『Write once, run anywhere』,焦点似乎并不在编译上,而是在对源文件的修改上。

三军评论:
Java特性:
面向对象(封装,继承,多态)
平台无关性(JVM运行.class文件)
语言(泛型,Lambda)
类库(集合,并发,网络,IO/NIO)
JRE(Java运行环境,JVM,类库)
JDK(Java开发工具,包括JRE,javac,诊断工具)

Java是解析运行吗?
不正确!
1,Java源代码经过Javac编译成.class文件
2,.class文件经JVM解析或编译运行。
(1)解析:.class文件经过JVM内嵌的解析器解析执行。
(2)编译:存在JIT编译器(Just In Time Compile 即时编译器)把经常运行的代码作为"热点代码"编译与本地平台相关的机器码,并进行各种层次的优化。
(3)AOT编译器: Java 9提供的直接将所有代码编译成机器码执行。

总结:

正如上文中名叫三军的网页总结的很好。

java是解释执行的吗?

不正确!

java代码通过javac编译成.class文件,.class文件经JVM解析或编译运行。所谓解释执行就是边翻译为机器码边执行,而(JIT编译器just in time)即时编译就是先将一个方法中的所有字节码全部编译成机器码之后再执行。解释执行不需要等待编译,翻译一部分就可以执行一部分,而后者在编译完成后,实际的运行速度更快,在HotSpot中默认采用混合模式,其先解释执行字节码,然后将其中的热点代码(多次执行,循环等)直接编译成机器码,下次就不用再编译了,让其更快速地运行。

编译器有两种:JIT编译器;AOT编译器:是在java9中提供的,将所有代码编译成机器码执行。

据作者说未来jre将推出历史舞台!大家拭目以待吧!

 

 

转载于:https://my.oschina.net/Pirvate/blog/3019353

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值