JAVA程序运行原理

       当我们真正运行程序的时候,CPU是读不懂这些英文的,所以我们需要先转化成可执行的二进制文件,这个过程通常由编译器完成。有些编译器直接将源代码编译成机器码,载入内存后CPU可以直接运行。而机器码的格式是跟具体的CPU架构相关的,Intel的CPU机器码对于ARM CPU来说是无法理解的。因此,同样的源代码需要根据不同的硬件进行特定的编译。好了,高级语言到低级语言的桥梁就是编译器。我们写好源代码,编译器将源码编译成可执行的机器码,然后CPU读取机器码,执行程序。

       Java源代码(.java)经过java编译器(javac.exe)编译之后,并没有直接转化为机器码,而是转化成一种中间格式,成为字节码(.class),字节码再经过java虚拟机转化成特定CPU架构的机器码。也正是因为这一中间物,java才有所谓的跨平台。

       .java 源代码编译==>.class ==>JVM

线程独占:每个线程都有它独立的空间,随线程生命周期而创建和销毁

线程共享:所有线程都能访问这块内存区域,随虚拟机或者GC而创建和销毁

方法区:JVM用来存储加载的类信息、常量池、静态变量、编译后的代码等数据,虚拟机规范中这是一个逻辑区,具体实现根据步同虚拟机来实现,如:Oracle的HotSpot在java7中方法区放在永久代,java8放在元数据空间,并且通过GC机制对这个区域进行管理。

堆内存:还可以细分为、新生代、老年代(Eden、From Survivor、To Survivor)JVM启动是创建,存放对象的实例。垃圾回收器主要就是管理堆内存。如果满了,就会出现OutOfMemroryError。

虚拟机栈:每个线程都在这个空间有一个私有的空间。线程栈由多个栈帧(Stack Frame)组成。一个线程栈会执行一个或多个方法,一个方法对应一个栈帧。栈帧内容包含:局部变量、操作数、动态链接、方法返回地址、附加信息等。栈内存默认最大是1M,超出则抛出StackOverflowError。

本地方法栈:和虚拟机栈功能类似,虚拟机是为虚拟机执行JAVA方法而准备的,本地方法栈是为虚拟机适用Native本地方法而准备的。虚拟机规范没有规定具体的实现,由不透的虚拟机厂商去实现。HotSpot虚拟机中虚拟机栈和本地方法栈的实现一样的。同样超出大小以后也会抛出StackOverflowError。

程序计数器:(Program Counter Register)记录当前线程执行字节码的位置,存储的是字节码指令地址,如果执行Native方法,则计数器值为空。每个线程都在这个空间由一个私有的空间,占用内存空间很少。CPU同一时间,只会执行一条线程中的指令。JVM多线程会轮流切换并分配CPU执行时间的方式,为了线程切换后,需要通过程序计数器,来恢复正确的执行位置。

编译下面java文件 javac,编译成class文件,利用javap命令的解析结果说明,查看Demo1.txt;

//编译

javac Demo1.java

//javap查看内容

javap -v Demo1.class>Demo1.txt

public class Demo1 {
    public int x;

    public int sum(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        demo1.x = 3;
        int y = 2;
        int z = demo1.sum(demo1.x, y);
        System.out.println("person age is " + z);
    }


}


 class内容


Classfile /D:/Demo1.class
  Last modified 2018-12-31; size 795 bytes
  MD5 checksum e4a628b971c32236aec9fb9b2672408d
  Compiled from "Demo1.java"
public class com.study.hc.thread.chapter1.thread.Demo1
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #14.#27        // java/lang/Object."<init>":()V
   #2 = Class              #28            // com/study/hc/thread/chapter1/thread/Demo1
   #3 = Methodref          #2.#27         // com/study/hc/thread/chapter1/thread/Demo1."<init>":()V
   #4 = Fieldref           #2.#29         // com/study/hc/thread/chapter1/thread/Demo1.x:I
   #5 = Methodref          #2.#30         // com/study/hc/thread/chapter1/thread/Demo1.sum:(II)I
   #6 = Fieldref           #31.#32        // java/lang/System.out:Ljava/io/PrintStream;
   #7 = Class              #33            // java/lang/StringBuilder
   #8 = Methodref          #7.#27         // java/lang/StringBuilder."<init>":()V
   #9 = String             #34            // person age is
  #10 = Methodref          #7.#35         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #11 = Methodref          #7.#36         // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  #12 = Methodref          #7.#37         // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #13 = Methodref          #38.#39        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #14 = Class              #40            // java/lang/Object
  #15 = Utf8               x
  #16 = Utf8               I
  #17 = Utf8               <init>
  #18 = Utf8               ()V
  #19 = Utf8               Code
  #20 = Utf8               LineNumberTable
  #21 = Utf8               sum
  #22 = Utf8               (II)I
  #23 = Utf8               main
  #24 = Utf8               ([Ljava/lang/String;)V
  #25 = Utf8               SourceFile
  #26 = Utf8               Demo1.java
  #27 = NameAndType        #17:#18        // "<init>":()V
  #28 = Utf8               com/study/hc/thread/chapter1/thread/Demo1
  #29 = NameAndType        #15:#16        // x:I
  #30 = NameAndType        #21:#22        // sum:(II)I
  #31 = Class              #41            // java/lang/System
  #32 = NameAndType        #42:#43        // out:Ljava/io/PrintStream;
  #33 = Utf8               java/lang/StringBuilder
  #34 = Utf8               person age is
  #35 = NameAndType        #44:#45        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #36 = NameAndType        #44:#46        // append:(I)Ljava/lang/StringBuilder;
  #37 = NameAndType        #47:#48        // toString:()Ljava/lang/String;
  #38 = Class              #49            // java/io/PrintStream
  #39 = NameAndType        #50:#51        // println:(Ljava/lang/String;)V
  #40 = Utf8               java/lang/Object
  #41 = Utf8               java/lang/System
  #42 = Utf8               out
  #43 = Utf8               Ljava/io/PrintStream;
  #44 = Utf8               append
  #45 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #46 = Utf8               (I)Ljava/lang/StringBuilder;
  #47 = Utf8               toString
  #48 = Utf8               ()Ljava/lang/String;
  #49 = Utf8               java/io/PrintStream
  #50 = Utf8               println
  #51 = Utf8               (Ljava/lang/String;)V
{
  public int x;
    descriptor: I
    flags: ACC_PUBLIC

  public com.study.hc.thread.chapter1.thread.Demo1();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 6: 0

  public int sum(int, int);
    descriptor: (II)I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=3
         0: iload_1
         1: iload_2
         2: iadd
         3: ireturn
      LineNumberTable:
        line 10: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=4, args_size=1
         0: new           #2                  // class com/study/hc/thread/chapter1/thread/Demo1
         3: dup
         4: invokespecial #3                  // Method "<init>":()V
         7: astore_1
         8: aload_1
         9: iconst_3
        10: putfield      #4                  // Field x:I
        13: iconst_2
        14: istore_2
        15: aload_1
        16: aload_1
        17: getfield      #4                  // Field x:I
        20: iload_2
        21: invokevirtual #5                  // Method sum:(II)I
        24: istore_3
        25: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
        28: new           #7                  // class java/lang/StringBuilder
        31: dup
        32: invokespecial #8                  // Method java/lang/StringBuilder."<init>":()V
        35: ldc           #9                  // String person age is
        37: invokevirtual #10                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        40: iload_3
        41: invokevirtual #11                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        44: invokevirtual #12                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        47: invokevirtual #13                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        50: return
      LineNumberTable:
        line 14: 0
        line 15: 8
        line 16: 13
        line 17: 15
        line 18: 25
        line 19: 50
}
SourceFile: "Demo1.java"


程序运行

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值