1)jvm有很多种,其实jvm是一个标准,sun做的那个叫hotspot,作者就是后来v8的作者lars bak,其他公司也做过jvm,其中做得比较好的有bea的jrockit,其他的包括ibm的r9,apple的jvm等在内,都做得不行,所以jvm主要是整合淘汰掉这些做得不好的jvm(s),整合成一个统一的openjdk。
2)java是典型的oop语言,其执行效率的优化,最早就是lars bak等人从smalltalk等长期优化的经验中总结出来并apply到hotspot上去滴,而smalltalk在早期apple机上搞出了那种拖拖拽拽就开发出app的做法,后来vc,delphi之类的其实都是抄袭或者说借鉴apple的smalltalk的做法,jobs说微软从头到尾都在抄袭apple是空穴来风,这里空穴来风跟王垠使用的空穴来风是一个意思,有趣的是,java的gui并没有继承这种搞法,反而对这种拖拖拽拽就作出app的做法批判有加,到今天,其实java的gui都还不能真正做到拖拖拽拽就作出来,问题很多,个人建议对于纯java的gui开发,还是以写代码为主。
3)jee也是一个或者说是一堆标准,知乎上有些人把maven,jenkins都算做jee是不对滴,jee的标准核心是ejb,其实就是一个xml配置化的java文件,这个标准在4的时候,达到了顶峰状态,几乎所有的挨踢大厂都主动支持该标准,之后开始走下坡路,支持的厂越来越少。
4)java和javascript的关系比很多人认为的要密切,javascript里面的java这四个字母可不是白叫的,比如js的版权和商标都控制在oracle手里,oracle对于js的支持甚至超过其对java的支持,并且喜欢捆绑销售,比如jvm里面就有一个js引擎。
5)jvm里面除了js engine以外还有一个浏览器排版引擎webkit,就是apple safari和google chrome用的那个那个。
6)java支持绝大多数脚本语言,你能叫得上名字的脚本语言,几乎都可以在jvm上执行,比如常见的js,ruby,python,甚至php,lua,只不过除了js以外你需要找到相关的脚本引擎。
7)spring的版权被控制在vmware手里,其实spring的那一大堆东西,本质上是一个非标准的jee实现,比如在jee里面用的inject,在spring里面就是autowire,当然spring曾经深刻滴影响了jee,所以有些东西比如di标准,是spring影响下制定出来的,所以spring的做法会比较特例一点。
8)maven上的jars数量前两天突破800万,其他语言的类库,排名第二的是npm,大概数量是maven的十分之一,也就是几十万,不知道现在突破100万没有,然后是gem,也就是ruby那个,大概是十几万,下来是python的module,大概数量级是几万,没突破十万。
9)java的标准是由一个叫做jcp的组织制定的,所有标准需要经过jcp的执行委员会通过方可执行,jcp几乎包括了你所知道的绝大多数知名挨踢公司和组织,比如google,apple,ibm,intel,arm,red hat,twitter等,还有一些教育机构,比如我国的北京大学,阿里最近一次申请jcp执行委员会成员资格,似乎投票不通过,最近一次执行委员会新增两个成员是arm和jetbrains。
10)微软也曾经是jcp甚至是java的主要贡献者,但是利益驱使下,想扩展java,从而破坏java跨平台的特性,所以跟sun闹翻,其本质原因就是想让客户写的java代码跟windows绑定,sun坚决不同意,闹翻,今天回头看这个结果,只能说:双输,sun挂了,微软的ria也离挂不太远了,silverlight已经放弃了,比起当年ie自带有jvm的支持来说,那完全就是两回事。
11)除了微软以外,jcp还缺少一个重要组织apache,因为apache跟oracle也闹翻了,oracle似乎并不在乎开源组织,而更在意商业公司的支持。
12)java曾经有一个内置的数据库,9之后被剥离。
13)j2me是j2se的子集。
14)vert.x作者tim fox最早在vmware做spring时候看到了node.js,萌生出了制作支持多核的node.x的想法,并在离开vmware后加入red hat将其实现,vmware看到后开始耍无赖,claim node.x后来改叫vert.x的版权,不惜跟red hat打官司,后来各方妥协,将其交给eclipse foundation。
15)oracle在收购bea之前,一开始的目标并不是bea和bea的weblogic,而是jboss,但是jboss表现出了极为有种的一面,在oracle收购成功之前,投入了red hat的怀抱,因为都是开源组织,从此jboss成了red hat的一个子部门,oracle收购jboss失败之后,转向bea,庄思浩气死了,但是没用,最后还是被恶意收购。
16)sun在玩不下去之前最早尝试接触的目标是ibm,ibm嫌太贵,放弃之后,被转手给了oracle。(Java学习交流QQ群:589809992 我们一起学Java!)
17)vert.x的作者tim fox在离开red hat之前曾经发过twitter抱怨,外人比如我们,猜测是因为red hat内部已经有了一个jboss,所以跟vert.x在应用上有了重叠,所以导致tim fox的出走,但是出走之后,red hat答应对vert.x做持续性的战略投入,所以vert.x core的几个developers,其实拿的是red hat的工资,但是vert.x的版权并不在red hat手里,而在eclipse foundation手里。
18)vert.x的几个核心开发人员都是google summer of code的导师,每年年初时候会招收在校大学生搞项目。
19)教育机构相关:scala的作者马丁是德国人,eth的博导,groovy的主要领导人是法国人,jruby背后是东京大学,jboss的作者是法国大学校x的校友,x就是伽罗瓦考不进去的那所大学,伽罗瓦进不了x,所以改读巴黎高师,tim fox毕业于帝国理工,主席去的那个,netty作者trustin lee是acm银牌,现在line工作,毕业于sky里面的延世大学,kotlin是毛子公司jetbrains的作品,看linkedin,很多人毕业自圣彼得堡大学,spring作者rod johnson是悉尼大学的音乐博士,hibernate作者gavin king是澳洲莫那什大学的数学本科毕业生,james gosling这种cmu和calgory的估计烂大街了,sun是斯坦福大学网络的意思,夹带两个私货,aspectj有一个维护小组在mcgill,hbase跟waterloo关系密切。
20)java早期被人认为慢,跟java坚持不用硬件加速渲染有关,死活就是不肯接入directx和opengl,7之后总算开窍,搞了一个图形引擎接入了directx/opengl。
21)casssandra是facebook做失败的项目,被贡献给了apache之后老树开花。
22)groovy被贡献给了apache,现在叫做apache groovy,ceylon被贡献给了eclipse,现在叫做eclipse ceylon。
23)netflix现在是java shop,之前是用.net的。
先想到这么多,有空再写。
Java语言引入了Java虚拟机 具有跨平台运行的功能 能够很好地适应各种Web应用 同时 为了提高Java语言的性能和健壮性 还引入了如垃圾回收机制等新功能 通过这些改进让Java具有其独特的工作原理
.Java虚拟机
Java虚拟机(Java Virtual Machine JVM)是软件模拟的计算机 它可以在任何处理器上(无论是在计算机中还是在其他电子设备中)安全兼容地执行保存在 class文件中的字节码 Java虚拟机的 机器码 保存在 class文件中 有时也可以称之为字节码文件
Java程序的跨平台特性主要是指字节码文件可以在任何具有Java虚拟机的计算机或者电子设备上运行 Java虚拟机中的Java解释器负责将字节码文件解释成为特定的机器码进行运行 因此在运行时 Java源程序需要通过编译器编译成为 class文件
Java虚拟机的建立需要针对不同的软硬件平台来实现 既要考虑处理器的型号 也要考虑操作系统的种类 由此在SPARC结构 X 结构 MIPS和PPC等嵌入式处理芯片上 在UNIX Linux Windows和部分实时操作系统上都可实现Java虚拟机
.无用内存自动回收机制
在程序的执行过程中 部分内存在使用过后就处于废弃状态 如果不及时进行回收 很有可能会导致内存泄漏 进而引发系统崩溃 在C++语言中是由程序员进行内存回收的 程序员需要在编写程序时把不再使用的对象内存释放掉 这种人为管理内存释放的方法往往由于程序员的疏忽而致使内存无法回收 同时也增加了程序员的工作量 而在Java运行环境中 始终存在着一个系统级的线程 专门跟踪内存的使用情况 定期检测出不再使用的内存 并自动进行回收 避免了内存的泄露 也减轻了程序员的工作量
.代码安全性检查机制
安全和方便总是相对矛盾的 Java编程语言的出现使得客户端计算机可以方便地从网络上上传或下载Java程序到本地计算机上运行 但是如何保证该Java程序不携带病毒或者没有其他危险目的呢?为了确保Java程序执行的安全性 Java语言通过Applet程序来控制非法程序的安全性 也就是有了它才确保Java语言的生存
Java字节码的执行需要经过以下 个步骤
( )由类装载器(class loader)负责把类文件( class文件)加载到Java虚拟机中 在此过程需要检验该类文件是否符合类文件规范
( )字节码校验器(bytecode verifier)检查该类文件的代码中是否存在着某些非法操作 例如Applet程序中写本地计算机文件系统的操作
( )如果字节码校验器检验通过 由Java解释器负责把该类文件解释成为机器码进行执行
注意
Java虚拟机采用 沙箱 运行模式 即把Java程序的代码和数据都限制在一定内存空间里执行 不允许程序访问该内存空间以外的内存 如果是Applet程序 还不允许访问客户端机器的文件系统
Java的运行环境
无论哪种语言都需要有它特定的运行环境 也就是平台 Java语言同样不例外 但是如何理解Java程序与硬件环境无关呢?
几乎所有的语言都需要通过编译或者解释才可以被计算机执行 但是Java有一点不同 它同时需要这两个过程 其实 也正是因为这个原因才使Java这种语言具有了平台无关性 当完成一个Java源程序后 首先 通过Java翻译程序将它编译成一种叫做字节码的中间代码 然后再由Java平台的解释器将它转换成为机器语言来执行 这一平台的核心就是JVM
Java的编译过程与其他的语言不同 像C++这样的语言 在编译时它是与计算机的硬件平台信息密不可分的 编译程序通过查表将所有指令的操作数和操作码等转换成内存的偏移量 即程序运行时的内存分配方式 目的是保证程序正常运行 而Java却是将指令转换成为一种 class的文件 这种文件不包含硬件的信息 需要执行时只要经过安装有JVM的机器进行解释 创建内存分配后再通过查表来确定一条指令所在的地址 这样就有效地保证了Java的可移植性和安全性
Java平台具有这样的特性和它的结构有关 通常一个程序运行的平台是一个硬件或者软件运行的环境 目前比较流行的是Windows XP Linux Solaris和MacOS Java的平台不太一样 它由两个部分组成 即JVM和应用程序设计接口
.JVM
JVM是Java平台的核心 为了让编译产生的字节码能更好地解释与执行 因此把JVM分成了 个部分 JVM解释器 指令系统 寄存器 栈 存储区和碎片回收区
◆JVM解释器 即这个虚拟机处理字段码的CPU
◆JVM指令系统 该系统与计算机很相似 一条指令由操作码和操作数两部分组成 操作码为 位二进制数 主要是为了说明一条指令的功能 操作数可以根据需要而定 JVM有多达 种不同的操作指令
◆寄存器 JVM有自己的虚拟寄存器 这样就可以快速地与JVM的解释器进行数据交换 为了功能的需要 JVM设置了 个常用的 位寄存器 pc(程序计数器) optop(操作数栈顶指针) frame(当前执行环境指针)和vars(指向当前执行环境中第一个局部变量的指针)
◆JVM栈 指令执行时数据和信息存储的场所和控制中心 它提供给JVM解释器运算所需要的信息
◆存储区 JVM存储区用于存储编译过后的字节码等信息
◆碎片回收区 JVM碎片回收是指将使用过的Java类的具体实例从内存进行回收 这就使得开发人员免去了自己编程控制内存的麻烦和危险 随着JVM的不断升级 其碎片回收的技术和算法也更加合理 JVM 版后产生了一种叫分代收集技术 简单来说就是利用对象在程序中生存的时间划分成代 以此为标准进行碎片回收
.Java应用程序设计接口
Java Application Programming Interface简称Java API 其中文名为Java应用程序设计接口 它是一个软件集合 其中有许多开发时所需要的控件 可以用它来辅助开发
lishixinzhi/Article/program/Java/hx/201311/26733
虚拟机:指以软件的方式模拟具有完整硬件,VM概念
虚拟机:指以软件的方式模拟具有完整硬件系统功能、运行在一个完全隔离环境中的完整计算机系统 ,是物理机的软件实现。常用的虚拟机有VMWare,Visual Box,Java Virtual Machine(Java虚拟机,简称JVM)。
Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够"一次编译,到处运行"的原因。
Java虚拟机阵营:Sun HotSpot VM、BEA JRockit VM、IBM J9 VM、Azul VM、Apache Harmony、Google Dalvik VM、Microsoft JVM…
启动流程


JVM由三个主要的子系统构成:
1.类加载器子系统
2.运行时数据区(内存)
3.执行引擎


JVM原理
JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器。它是一种基于下层的操作系统和硬件平台并利用软件方法来实现的抽象的计算机,可以在上面执行java的字节码程序。
java编译器只需面向JVM,生成JVM能理解的代码或字节码文件。Java源文件经编译器,编译成字节码程序,通过JVM将每一条指令翻译成不同平台机器码,通过特定平台运行。
JVM执行程序的过程 :
I.加载.class文件
II.管理并分配内存
III.执行垃圾收集
JRE(java运行时环境)包含JVM的java程序的运行环境
JVM是Java程序运行的容器,但是他同时也是操作系统的一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间。
JVM在整个jdk中处于最底层,负责与操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也叫虚拟计算机.操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境。
1.创建JVM装载环境和配置
2.装载JVM.dll
3.初始化JVM.dll并挂接到JNIENV(JNI调用接口)实例
4.调用JNIEnv实例装载并处理class类。
寄存器
所有的CPU均包含用于保存系统状态和处理器所需信息的寄存器组。如果虚拟机定义较多的寄存器,便可以从中得到更多的信息而不必对栈或内存进行访问,这有利于提高运行速度。然而,如果虚拟机中的寄存器比实际CPU的寄存器多,在实现虚拟机时就会占用处理器大量的时间来用常规存储器模拟寄存器,这反而会降低虚拟机的效率。针对这种情况,JVM只设置了4个最为常用的寄存器。它们是:
pc程序计数器
optop操作数栈顶指针
frame当前执行环境指针
vars指向当前执行环境中第一个局部变量的指针
所有寄存器均为32位。pc用于记录程序的执行。optop,frame和vars用于记录指向Java栈区的指针。寄存器
栈结构
作为基于栈结构的计算机,Java栈是JVM存储信息的主要方法。当JVM得到一个Java字节码应用程序后,便为该代码中一个类的每一个方法创建一个栈框架,以保存该方法的状态信息。每个栈框架包括以下三类信息:
局部变量
执行环境
操作数栈
局部变量用于存储一个类的方法中所用到的局部变量。vars寄存器指向该变量表中的第一个局部变量。
执行环境用于保存解释器对Java字节码进行解释过程中所需的信息。它们是:上次调用的方法、局部变量指针和操作数栈的栈顶和栈底指针。执行环境是一个执行一个方法的控制中心。例如:如果解释器要执行iadd(整数加法),首先要从frame寄存器中找到当前执行环境,而后便从执行环境中找到操作数栈,从栈顶弹出两个整数进行加法运算,最后将结果压入栈顶。
操作数栈用于存储运算所需操作数及运算的结果。
运行数据
JVM定义了若干个程序执行期间使用的数据区域。这个区域里的一些数据在JVM启动的时候创建,在JVM退出的时候销毁。而其他的数据依赖于每一个线程,在线程创建时创建,在线程退出时销毁。分别有程序计数器,堆,栈,方法区,运行时常量池。
运行过程
上面对虚拟机的各个部分进行了比较详细的说明,下面通过一个具体的例子来分析它的运行过程。
虚拟机通过调用某个指定类的方法main启动,传递给main一个字符串数组参数,使指定的类被装载,同时链接该类所使用的其它的类型,并且初始化它们。新建一java源文件并取名HelloApp.java,内容如下:
class HelloApp {
public static void main(String[] args) {
System.out.println("Hello World!");
for (int i = 0; i args.length; i++ ) {
System.out.println(args);
}
}
}
在命令模式下输入:javac HelloApp.java 进行编译,这时同目录下会产生一个编译后的文件:HelloApp.class
然后在命令行模式下键入:java HelloApp run virtual machine
将通过调用HelloApp的方法main来启动java虚拟机,传递给main一个包含三个字符串"run"、"virtual"、"machine"的数组。我们略述虚拟机在执行HelloApp时可能采取的步骤。


JVM虚拟机运行过程
开始试图执行类HelloApp的main方法,发现该类并没有被装载,也就是说虚拟机当前不包含该类的二进制代表,于是虚拟机使用ClassLoader试图寻找这样的二进制代表。如果这个进程失败,则抛出一个异常。类被装载后同时在main方法被调用之前,必须对类HelloApp与其它类型进行链接然后初始化。链接包含三个阶段:检验,准备和解析。检验检查被装载的主类的符号和语义,准备则创建类或接口的静态域以及把这些域初始化为标准的默认值,解析负责检查主类对其它类或接口的符号引用,在这一步它是可选的。类的初始化是对类中声明的静态初始化函数和静态域的初始化构造方法的执行。一个类在初始化之前它的父类必须被初始化。