一、Java的class文件的内容

  1.首先编写一个简单的代码

  public class StringDemo {

  public static void main(String[] args) {

  String s=new String("hello world");

  System.out.println(s);

  }

  }

  2.运行程序编译成class文件,class文件的查看可以用Java class文件分析工具 -- Classpy

  3.这种字节码文件我们肯定看不懂,所以我们可以通过指令Javap来转换成我们人类可以看懂的

  

  4.打开StringDemo.txt文件,即下图的内容

  public class com.dada.demo.controller.StringDemo

  minor version: 0

  major version: 52

  flags: ACC_PUBLIC, ACC_SUPER

  Constant pool:

  #1 = Methodref #8.#24 // java/lang/Object."":()V

  #2 = Class #25 // java/lang/String

  #3 = String #26 // hello world

  #4 = Methodref #2.#27 // java/lang/String."":(Ljava/lang/String;)V

  #5 = Fieldref #28.#29 // java/lang/System.out:Ljava/io/PrintStream;

  #6 = Methodref #30.#31 // java/io/PrintStream.println:(Ljava/lang/String;)V

  #7 = Class #32 // com/dada/demo/controller/StringDemo

  #8 = Class #33 // java/lang/Object

  #9 = Utf8

  #10 = Utf8 ()V

  #11 = Utf8 Code

  #12 = Utf8 LineNumberTable

  #13 = Utf8 LocalVariableTable

  #14 = Utf8 this

  #15 = Utf8 Lcom/dada/demo/controller/StringDemo;

  #16 = Utf8 main

  #17 = Utf8 ([Ljava/lang/String;)V

  #18 = Utf8 args

  #19 = Utf8 [Ljava/lang/String;

  #20 = Utf8 s

  #21 = Utf8 Ljava/lang/String;

  #22 = Utf8 SourceFile

  #23 = Utf8 StringDemo.java

  #24 = NameAndType #9:#10 // "":()V

  #25 = Utf8 java/lang/String

  #26 = Utf8 hello world

  #27 = NameAndType #9:#34 // "":(Ljava/lang/String;)V

  #28 = Class #35 // java/lang/System

  #29 = NameAndType #36:#37 // out:Ljava/io/PrintStream;

  #30 = Class #38 // java/io/PrintStream

  #31 = NameAndType #39:#34 // println:(Ljava/lang/String;)V

  #32 = Utf8 com/dada/demo/controller/StringDemo

  #33 = Utf8 java/lang/Object

  #34 = Utf8 (Ljava/lang/String;)V

  #35 = Utf8 java/lang/System

  #36 = Utf8 out

  #37 = Utf8 Ljava/io/PrintStream;

  #38 = Utf8 java/io/PrintStream

  #39 = Utf8 println

  {

  public com.dada.demo.controller.StringDemo();

  descriptor: ()V

  flags: ACC_PUBLIC

  Code:

  stack=1, locals=1, args_size=1

  0: aload_0

  1: invokespecial #1 // Method java/lang/Object."":()V

  4: return

  LineNumberTable:

  line 3: 0

  LocalVariableTable:

  Start Length Slot Name Signature

  0 5 0 this Lcom/dada/demo/controller/StringDemo;

  public static void main(java.lang.String[]);

  descriptor: ([Ljava/lang/String;)V

  flags: ACC_PUBLIC, ACC_STATIC

  Code:

  stack=3, locals=2, args_size=1

  0: new #2 // class java/lang/String

  3: dup

  4: ldc #3 // String hello world

  6: invokespecial #4 // Method java/lang/String."":(Ljava/lang/String;)V

  9: astore_1

  10: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;

  13: aload_1

  14: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

  17: return

  LineNumberTable:

  line 5: 0

  line 6: 10

  line 7: 17

  LocalVariableTable:

  Start Length Slot Name Signature

  0 18 0 args [Ljava/lang/String;

  10 8 1 s Ljava/lang/String;

  }

  SourceFile: "StringDemo.java"

  5.上面的内容我们可以根据jvm指令码表,就知道什么意思啦

  二、Java运行时数据区

  1.方法区

  Jvm用来存储加载类的信息、常量、静态变量、编译后的代码等数据

  2.堆内存

  Jvm启动时创建,存放对象的实例。垃圾回收器主要就是管理堆内存。

  3.虚拟机栈

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

  4.本地方法栈 无锡人流医院哪家好 http://mobile.wxbhnkyy120.com/

  和虚拟机栈功能类似,虚拟机栈是为虚拟机执行JAVA方法而准备的,本地方法栈是为虚拟机使用Native本地方法而准备的。

  5.程序计数器

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

  在了解上面的基础知识后,我们开始了解具体的执行过程。

  三、Java虚拟机如何运行Java字节码?

  标准JDK中的HotSpot是如何运行Java字节码的呢?(常见的虚拟机分三种1.HotSpot 2. JRockit 3.IBM的jvma)

  需要从两个角度考虑:

  虚拟机角度

  底层硬件角度

  1.1虚拟机角度

  1.1.1从虚拟机角度是如何运行Java字节码的?

  ①首先会将Java代码编译成的class文件加载到JVM

  ②加载后的Java类会存放到方法区中。

  ③实际运行时,JVM会执行方法区内的代码。

  ④运行时,每当调用进入一个Java方法,JVM会在当前线程的Java方法栈中生成一个栈帧。

  ⑤退出执行的Java方法时,无论是不是正常返回,JVM都会弹出并舍弃掉当前线程的当前栈帧。

  1.1.2栈帧是什么?

  ①用于存放局部变量、字节码的操作数

  ②栈帧的大小是提前计算好的。

  ③JVM不要求栈帧在内存空间内连续分布。

  1.1.3JVM中内存组成部分有哪些?线程共享的是哪些部分?线程私有的是哪些部分?

  线程共享:

  ①方法区:存放加载后的Java类

  ②堆:创建的对象实例

  线程私有:

  ①Java方法栈: 面向Java方法

  ②本地方法栈: 面向C++写的native方法

  ③PC寄存器: 存放各个线程执行位置。

  2.1硬件角度

  2.1.1从硬件角度角度是如何运行Java字节码的?

  ①Java字节码无法直接执行

  ②JVM需要将字节码翻译成机器码

  2.1.2JVM(如HotSpot)如何将字节码翻译成机器码?

  两种方法:

  ①解释执行-逐条将字节码翻译成机器码执行

  ②即时编译(Just-In-Time compilation, JIT)-将一个方法中的字节码都编译成机器码后再执行。

  总结:

  Hello.java-->被编译成Hello.class,然后被加载到jvm的虚拟机里,存放到方法区内。实际运行代码时执行方法区的代码,每当调用进入一个Java方法,JVM会在当前线程的Java方法栈中生成一个栈帧,在栈帧内操作数栈根据指令码的顺序操作本地变量表来实现代码的执行,退出执行的Java方法时,无论是不是正常返回,JVM都会弹出并舍弃掉当前线程的当前栈帧。

Java虚拟机如何运行Java字节码的更多相关文章

  1. 深入理解Java虚拟机06--虚拟机字节码执行引擎

    一.前言 物理机的执行引擎是直接在物理硬件如CPU.操作系统.指令集上运行的,但是对于虚拟机来讲,他的执行引擎由自己实现. 执行引擎有统一的外观(Java虚拟机规范),不同类型的虚拟机都遵循了这一规范 ...

  2. 深入理解java虚拟机(六)字节码指令简介

    Java虚拟机指令是由(占用一个字节长度.代表某种特定操作含义的数字)操作码Opcode,以及跟随在其后的零至多个代表此操作所需参数的称为操作数 Operands 构成的.由于Java虚拟机是面向操作 ...

  3. 深入理解java虚拟机(5)---字节码执行引擎

    字节码是什么东西? 以下是百度的解释: 字节码(Byte-code)是一种包含执行程序.由一序列 op 代码/数据对组成的二进制文件.字节码是一种中间码,它比机器码更抽象. 它经常被看作是包含一个执行 ...

  4. 深入解析java虚拟机-jvm运行机制

    转自oschina 一:JVM基础概念 JVM(Java虚拟机)一种用于计算设备的规范,可用不同的方式(软件或硬件)加以实现.编译虚拟机的指令集与编译微处理器的指令集非常类似.Java虚拟机包括一套字 ...

  5. <<深入Java虚拟机>>-第二章-Java内存区域-学习笔记

    Java运行时内存区域 Java虚拟机在运行Java程序的时候会将它所管理的内存区域划分为多个不同的区域.每个区域都有自己的用途,创建以及销毁的时间.有的随着虚拟机的启动而存在,有的则是依赖用户线程来 ...

  6. Java虚拟机及运行时数据区

    1.Java虚拟机的定义 Java虚拟机(Java Virtual Machine),简称JVM.当我们说起Java虚拟机时,可能指的是如下三种不同的东西: 抽象的虚拟机规范 规范的具体实现 一个运行 ...

  7. JVM学习001通过实例总结Java虚拟机的运行机制

    JVM学习(1)——通过实例总结Java虚拟机的运行机制-转载http://www.cnblogs.com/kubixuesheng/p/5199200.html 文章转载自:http://www.c ...

  8. Java虚拟机一 运行时数据区(栈、堆、方法区等)

    Java虚拟机的内存管理主要分两点:内存分配以及内存回收.· 一.内存分配图: 注: 所占区域的大小与实际的内存大小比例并无直接关系. 解读: 1.如图,分成两种颜色的内存区域,其中蓝色的是线程隔离的 ...

  9. Java虚拟机_运行时数据区

    Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途.各自的创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程启动 ...

随机推荐

  1. Android之WebRTC介绍

    参考自:Introduction to WebRTC on AndroidAndroid之WebRTC介绍 WebRTC被誉为是web长期开源开发的一个新启元,是近年来web开发的最重要创新.WebR ...

  2. Linux安装fcitx输入法(命令安装)

    Linux安装fcitx输入法(命令安装)   打开终端安装输入法 sudo apt-get install im-switch libapt-pkg-perl fcitx fcitx-table-w ...

  3. tensorflow 笔记 15:如何使用 Supervisor

    如何使用Supervisor在不使用Supervisor的时候,我们的代码经常是这么组织的 variables ... ops ... summary_op ... merge_all_summari ...

  4. sql 时间段交叉查询是否有交集

    --双11活动结束时间大于当前服务器时间代表有效期的活动 --实现1 select * from ProdCar A where A.EndDate> GETDATE() and A.EndDa ...

  5. layui flow loading占位图实现方法

    如果流图片要加载失败, 就会显示找不到图片的裂痕 代码如下: <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  6. “无法启动IIS Express Web服务器”的解决办法

    “无法启动IIS Express Web服务器”的解决办法 听语音 原创 | 浏览:259 | 更新:2019-07-15 13:02 1 2 3 4 5 6 7 分步阅读 在使用visual stu ...

  7. java Random 随机密码

    /** * Created by xc on 2019/11/23 * 生成随机密码:6位数字 */public class Test7_4 { public static void main(Str ...

  8. 深入理解Python变量与常量

    深入理解Python变量与常量 变量是计算机内存中的一块区域,变量可以存储规定范围内的值,而且值可以改变.基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中.常量是一块只读的内 ...

  9. 使用命令行操作vmware esxi -- powershell

    之前提到过用linux命令行的方法操作vmware,这节我们来使用powershell的方式来操作.在操作之前需要下载安装一款命令行工具PowerCLI,本节只列出一些常用命令. 个人认为powerc ...

  10. Windows版的OpenJDK下载(Red Hat 提供)

    OpenJDK 在linux下安装很简单(yum安装),但是OpenJDK的官网没有为我们提供Windows版的安装软件.庆幸的是,Red Hat(红帽)为我们提供了windows版的安装软件. 下载 ...