深入JVM内核(一)

JAVA 2015-12-03

首先让我们了解一下什么是JAVA虚拟机。

  • 免去长篇大论,简单来说,JAVA虚拟机是指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。除了JVM,虚拟机还包括VMWare,Visual Box。其中VMWare或者Visual Box都是使用软件模拟物理CPU的指令集,而JVM使用软件模拟Java 字节码的指令集。

  • 下面来简单谈一谈JVM的发展历史,所谓知往昔而见未来,了解编程语言的发展历史绝非一无是处,这里简单介绍,感兴趣的朋友可以深入了解:
  • 1996年 SUN JDK 1.0 Classic VM;
  • 1997年 JDK1.1 发布;
  • 1998年 JDK1.2 Solaris Exact VM;
  • 2000年 JDK 1.3 Hotspot 作为默认虚拟机发布;
  • 2002年 JDK 1.4 Classic VM退出历史舞台等。 ...............
  • 2010年Oracle 收购 Sun 得到Hotspot
  • 2011年 JDK7发布
    • 延误项目推出到JDK8
    • G1
    • 动态语言增强
    • 64位系统中的压缩指针
    • NIO 2.0
  • 2014年 JDK8发布
    • Lambda表达式
    • 语法增强 Java类型注解
  • 2016年JDK9
    • 模块化 Oracle宣布在JDK8时整合JRockit和Hotspot,优势互补,在Hotspot基础上,移植JRockit优秀特性 ...............

我们顺便来看看JAVA的体系结构:

java.png 顺便附上Java7语言规范.pdfJVM7规范.pdf 下载链接

  • 可以看出在最新的JDK8中,HotSpot已经成为了主要虚拟机且处于底层的重要位置,任何Java代码都需要经过它的编译才能运行。

  • 那么我们为什么要学习JVM呢?

    • 简单来说就是,深入,深入,再深入!普通的程序员只需要编写应用程序,而如果想要理解JAVA运行的底层机制并对代码调优,那么非知道JVM不可。同时如果你不了解JVM的运行机制,那么在一个大型项目中,不可避免地会发生各种问题,这不仅会造成程序运行效率低下,甚至导致崩溃,但是调整又不知从何入手,那个时候你大概就可以“goback home”了。

我也将在接下来的博客中继续介绍。

下面来谈一谈JVM的规范

这里可谓名目繁杂,捡重要的说,其它的可以参考附件

  • 词法结构:

    1. \u + 4个16进制数字 表示UTF-16

    2. 行终结符: CR, or LF, or CR LF.

    3. 空白符 空格 tab \t 换页 \f 行终结符

    4. 注释

    5. 提示符

    6. 关键字

      • Int 0 2 0372 0xDada_Cafe 1996 0x00_FF__00_FF
      • Long 0l 0777L 0x100000000L 2_147_483_648L 0xC0B0L
      • Float 1e1f 2.f .3f 0f 3.14f 6.022137e+23f
      • Double 1e1 2. .3 0.0 3.14 1e-9d 1e137
    7. 操作 +=  -=  *=  /=  &=  |=  ^=  %=  <<=  >>=  >>>=
      • 类型和变量:
    8. 元类型 byte short int long float char
    9. 变量初始值 boolean false char \u0000
    10. 泛型
      • 举例:Java语言规范
    package com.myproject;

    class Value { 
        int val; 
    }
    public class Test {
        public static void main(String[] args) {
            int i1 = 3;
            int i2 = i1;
            i2 = 4;         //i1=3;i2=4
            System.out.print("i1==" + i1);
            System.out.println(" but i2==" + i2);
            Value v1 = new Value();
            v1.val = 5;
            Value v2 = v1;  //v1.val=v2.val=5
            v2.val = 6;     //v1.val=v2.val=6
            System.out.print("v1.val==" + v1.val);
            System.out.println(" and v2.val==" + v2.val);
        }
    }

总结:i1,i2为变量,而v1,v2则为同一地址的引用

运行结果是:i1==3 but i2==4 v1.val==6 and v2.val==6

  • VM指令集:
    • 类型转化 l2i
    • 出栈入栈操作 aload astore
    • 运算 iadd isub
    • 流程控制 ifeq ifne
    • 函数调用 invokevirtual invokeinterface invokespecial invokestatic
  • 附:JVM需要对Java Library 提供以这些支持:反射 java.lang.reflect;ClassLoader;初始化class和interface;安全相关 java.security;多线程;弱引用。
  • Java的编译方式:
  • 源码到JVM指令的对应格式
  • Javap
  • JVM反汇编的格式 <index> <opcode> [ <operand1> [ <operand2>... ]] [<comment>]
  • 例子
void spin() {              0   iconst_0 // Push int constant 0
  int i;                   1   istore_1 // Store into local variable 1 (i=0)
  for (i = 0; i < 100; i++) {  2   goto 8   // First time through don't increment
  // loop                  5   iinc 1 1 // Increment local variable 1 by 1 (i++)
     }                     8   iload_1  // Push local variable 1 (i)
  }                        9   bipush 100 // Push int constant 100
                           11  if_icmplt 5 // Compare and loop if less than (i < 100)
                           14  return  // Return void when done

附件:

  • Java7语言规范.pdf
  • [JVM7规范.pdf][5]

  • 本文由 Tony 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

    赏个馒头吧