深入理解JVM虚拟机

深入理解ART虚拟机—ART的函数运行机制 前面两篇文章介绍了ART的启动过程,而在启动之后,我们感兴趣的就是ART是怎么运行的。回顾一下虚拟机系列的前面几篇文章,我们可以理一下思路: 一,apk以进程的形式运行,进程的创建是由zygote。 参考文章《深入理解Dalvik虚拟机- Android应用进程启动过程分析》 二,进程运行起来之后,初始化JavaVM 参考文章《深入理解ART虚拟机—虚拟机的启动》 三,JavaVM创建之 阅读详情
  • JVM平台上还可以运行其他语言,运行的是Class字节码。只要能翻译成Class的语言就OK了。挺强大的。
  • JVM厂商很多
  • 垃圾收集器、收集算法
  • JVM检测工具

 

关于类的加载:

  •  Java代码中,类型(interface, class,enum等,有些是在运行时候生成的,比如动态代理)的加载、连接与初始化过程都是在程序运行期间完成的。不涉及到对象的概念。同时也是个Runtime阶段。
  •  提供了更大的灵活性,增加了更多的可能性。提供了一些扩展,灵活扩展。

    

Java虚拟机与程序的生命周期:

  在如下几种情况下,Java虚拟机将会结束生命周期:

  1. 执行了System.exit()方法
  2. 程序正常执行结束
  3. 程序执行过程遇到了异常或者错误异常终止了
  4. 操作系统出现错误导致Java虚拟机进行终止

 

类的加载、连接与初始化:

加载:查找并加载类的二进制数据

连接: 

  • 验证: 确保被加载类的正确性。Class有格式的。
  • 准备:为类的静态变量分配内存,并将其初始化为默认值  
  • 注:
    1.类的静态变量或类的静态方法,通常可以看做全局的,由类去直接调用。此时还是个类的概念,不存在对象。
    2.关于默认值问题:
    class Test{
    public static int a = 1;
    }
    中间过程: Test类加载到内存的过程中,会给a分配一个内存。然后将a初始化为默认值0(整型变量)

  • 解析: 把类中的符号引用转为直接引用。符号的引用也是间接的引用方式。

初始化: 为类的静态变量赋予正确的初始值

  • class Test{
       public static int a = 1;
      }
    此时的a才真正成为1了
    

      

类的使用与卸载

 使用: 类的方法变量使用等

 卸载: class字节码文件,加载到内存里面。形成了自己的数据结构,驻留在内存里面。可以销毁掉。卸载到了就不能进行new 对象了。

 

总体流程:

 

 

 

Java程序对类的使用方式分为两种:

  1. 主动使用
  2. 被动使用

 

所有的Java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始化他们。即初始化只会执行一次。

 

主动使用,七种(非精确划分,大体划分):

  1. 创建类的实例。
  2. 访问某个类或接口的静态变量,或者对静态变量赋值。 字节码层面上,使用的助记符:get static、  put static
  3. 调用类的静态方法。 invoke static
  4. 反射(如Class.forName("com.test.t1"))
  5. 初始化一个类的子类
    比如:
    
     class Parent{}
     class Child extends Parent{}
    
    初始化Child时候,先去初始化Parent 
  6. Java虚拟机启动时被表明为敌情类的类(Java Test)
    Java虚拟机启动时候,被标明为启动的类,即为有main方法的类,也会主动使用 
  7. JDK1.7开始提供动态语言支持:
    注:
    1.java.lang.invoke.MethodHandle实例的解析结果REF_getStatic, REF_putStatic, REF_invokeStatic句柄对应的类没有初始化,则初始化
    2.1.7开始提供了对动态语言的支持。特别的JVM平台上通过脚本引擎调用JS代码(动态语言)。  

注:助记符了解即可

 

除了以上七种情况,其他使用Java类的方式都被看做是对类的被动使用,都不会导致类的初始化。

 

类的加载:

 类的加载指的是将类 .class文件中的二进制数据读入内存中,将其放在运行时数据区的方法区内,然后在内存中创建一个java.lang.Class对象(规范并说明Class对象位于哪里,HotSpot虚拟机将其放在了方法区中,JVM没有规范这个)用来封装类在方法区内的数据结构。

 引申:一个类不管生成了多少实例,所有的实例对应只有一份Class对象。 Class对象是面镜子,能反映到方法区中的Class文件的内容、结构等各种信息。

加载.class文件的方式:

  1. 从本地系统中直接加载
  2. 通过网络下载
  3. 从zip、jar等贵方文件中加载
  4. 从转悠数据库中提取
  5. 将Java源文件动态编译为.class文件

 

public class MyTest1 {
    public static void main(String[] args) {
        System.out.println(MyChild1.str1);
//        System.out.println(MyChild1.str2);
    }
}

class MyParent1{

    //静态成员变量
    public static String str1 = "str1";
    // 静态代码块(程序加载初始化时候去执行)
    static {
        System.out.println("MyParent1 -----> static block running");
    }
}
class MyChild1 extends MyParent1{
    //静态成员变量
    public static String str2 = "str2";
    static {
        System.out.println("MyChild1 -----> static block running");
    }
}

  

 

 

 

str1 子类调用了继承到的父类的str1,子类的静态代码块没有执行。str1是父类中定义的。MyParent1的主动使用,但是没有主动使用MyChild1. 总结:看定义的!

 

 

str2 可以执行,同时初始化子类时候,父类会主动使用。所有的父类都会被初始化!

 

MyTest1是一个启动类,主动使用。先加载之。 

 

总结: 

  1. 对于静态字段来说,只有直接定义了该字段的类才会被初始化。
  2. 当一个类在初始化时候,要求其父类全部已经初始化完毕。每个父类最多只能初始化一次! 

 

引申: -XX:+TraceClassLoading,用于追踪类的加载信息并打印出来。可以看到类的加载情况。

           打印: 虚拟机在当前启动情况下所加载的类的信息。

 

总结设置方式:

所有JVM参数都是: -XX: 开头  

  类似于Boolean类型的开关:

        -XX:+<option> 表示开启option选项

        -XX: - <option>  表示关闭option选项

  赋值:   

     -XX:<option>=<value>, 表示将option选项的值设置为value  

 

 

 关于常量:

public class MyTest2 {

    public static void main(String[] args) {
        System.out.println(MyParent2.str);
    }
}

class MyParent2{

    // final修饰成为常量
    public static final String str = "hello world";

    static {
        System.out.println("MyParent2 ----> run");
    }

}

 

 

 

 

在编译阶段这个常量被存入到 调用这个常量的方法所在的类的常量池中。

本例中:

   “hello world”是一个常量,会放置到MyTest2类的常量池中。

   这里指的时将常量存放到了MyTest2的常量池汇总,之后MyTest2与MyParent2就没有任何关系了

   甚至,极端一些。我们可以将MyParent3的class文件删除。(编译完毕后,把class字节码删除)

 

总结:

  •  常量编译阶段会存入到调用这个常量的方法所在的类的常量池中。
  •  本质上,调用类并没有直接引用到定义常量的类,因此并不会触发定义常量类的初始化。

 

引申反编译: javap -c  类的全路径名字

 

助记符引申:

  • ldc表示将int,float 或 String类型的常量值从常量池中推送至栈顶。
  • bipush表示将单字节(-128 ~ 127)的常量值推送至栈顶  
  • sipush表示将一个短整型常量值(-32768 ~ 32767)推送至栈顶
  • iconst_1 表示将int类型的1推送至栈顶 (iconst_1 ~ iconst_5)

助记符是在rt.jar中相关类去实现的。

 

 

如果常量的值,在编译器不能确定下来呢?

public class MyTest3 {
    public static void main(String[] args) {
        System.out.println(MyParent3.str);
    }
}

class MyParent3 {
    public static final String str = UUID.randomUUID().toString();
    static {
        System.out.println("MyParent3 -- run");
    }
}

 

 

此时放在MyTest3类的常量池中没有意义的。

 

总结:  

  当一个常量值并非编译期间可以确定的,那么其值就不会被放到调用类的常量池中。这时在程序运行时,会导致主动使用这个常量所在的类,显然会导致这个类被初始化。

 

new对象实例情况:

public class MyTest4 {
    public static void main(String[] args) {
        MyParent4 myParent4 = new MyParent4();
    }
}
class MyParent4{
    static {
        System.out.println("MyParent4 --> run");
    }
}

对这个类的主动使用。

如果多次new,只会初始化一次。首次主动使用。

 

数组情况:

public class MyTest4 {
    public static void main(String[] args) {
        MyParent4[] myParent4s = new MyParent4[1];
    }
}
class MyParent4{
    static {
        System.out.println("MyParent4 --> run");
    }
}

不在七种情况范围内。不会初始化!

不是MyParent4的实例!

到底创建的什么实例?getClass!,数组的实例到底是个啥玩意儿?

public class MyTest4 {
    public static void main(String[] args) {
        MyParent4[] myParent4s = new MyParent4[1];
        //看看是啥
        Class<? extends MyParent4[]> aClass = myParent4s.getClass();
        System.out.println(aClass);
    }
}
class MyParent4{
    static {
        System.out.println("MyParent4 --> run");
    }
}

Java虚拟机在运行期,创建出来的类型。是个数组类型。有点类似动态代理

 

数组类型也是比较特殊的。[Lxxxx

二维数组也是一样的特殊

 

看下父类型:

public class MyTest4 {
    public static void main(String[] args) {
        MyParent4[] myParent4s = new MyParent4[1];
        //看看是啥
        System.out.println(myParent4s.getClass().getSuperclass());
    }
}
class MyParent4{
    static {
        System.out.println("MyParent4 --> run");
    }
}

父类型其实是Object

 

 

 

总结:

 对于数组实例来说,其类型是由JVM在运行期动态生成的

 动态生成的类型,其父类就是Object

 对于数组来说,JavaDoc经常将构成数组的元素为Component,实际上就是将数组降低一个维度后的类型。

 

看下原生类型的数组:

public class MyTest4 {
    public static void main(String[] args) {
       int[] ints = new int[3];
        System.out.println(ints.getClass());
        System.out.println(ints.getClass().getSuperclass());
    }
}
class MyParent4{
    static {
        System.out.println("MyParent4 --> run");
    }
}

 

 

 

助记符:

  anewarray: 表示创建一个引用类型的(比如类、接口、数组)数组,并将其引用值压如栈顶。

  newarray: 表示创建一个指定的原始类型(如:int,float,char等)的数组,并将其引用值压入栈顶。

 

以上所总结的是类与类之间的关系,包括继承的。下面接口的特点:

public class MyTest5 {
    public static void main(String[] args) {
        System.out.println(MyChild5.b);
    }
}

interface MyParent5 {
    public static int a = 5;
}

interface MyChild5 extends MyParent5 {
    public static int b = 6;
}

  接口是没有静态代码块的。可以通过手动删除class文件来证明之。

 

public class MyTest5 {
    public static void main(String[] args) {
        System.out.println(MyChild5.b);
    }
}

interface MyParent5 {
    public static int a = 5;
}

interface MyChild5 extends MyParent5 {
    // 只有在运行时候才会赋值,会放到MyTest5的常量池里面。如果Class删除了,运行时候就会报错!
    public static int b = new Random().nextInt(2);
}

 

  结论:

  • 当一个接口在初始化时候,并不要求其父类接口都完成了初始化。
  • 只有在真正使用到父类接口的时候(如引用接口中定义的常量时),才会初始化。
  • 类,一定要先初始化父类。

 

public class MyTest6 {
    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        System.out.println("counter"+ instance.counter1);
        System.out.println("counter"+ instance.counter2);
    }
}
class Singleton{
    public static int counter1;
    public static int counter2 = 0;

   private static Singleton singleton = new Singleton();

   private Singleton(){
       counter1++;
       counter2++;
   }
   public static Singleton getInstance(){
       return singleton;
   }
}

 

 

分析: 先赋值: 默认的0 和 给定的0,然后构造方法进行++操作。 

 

如果更改位置:

public class MyTest6 {
    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        System.out.println("counter1-->"+ instance.counter1);
        System.out.println("counter2-->"+ instance.counter2);
    }
}
class Singleton{
    public static int counter1;
   private static Singleton singleton = new Singleton();

   private Singleton(){
       counter1++;
       counter2++;
       System.out.println(counter1);
       System.out.println(counter2);
   }
    public static int counter2 = 0;

    public static Singleton getInstance(){
       return singleton;
   }
}

 

按照从上到下的顺序进行初始化。

类主动使用时候,先准备,给类的静态变量赋初始值。

此时: 

   counter1 初始值 0 

   singleton 初始值 null

   counter2 初始值 0

接着调用静态方法 getInstance时候,赋初始值。

sigleton 会指向一个实例,然后执行私有构造方法。

然后执行到 public static int counter2 = 0时候,显示赋值0了。

 

总结:

 先准备

 再初始化: 根据类里面代码的顺序去执行的.真正的赋值(准备为其提供初始值,要不谈不上做++操作)

 

 

 

 

 画个图:

 

 

 关于类的实例化:

  为对象分配内存,即为new对象,在堆上面。

   为实例变量赋默认值、为实例变量赋正确的初始值都跟静态变量似的了。赋予默认值之后,再去赋予开发者指定的值。

 

类的加载:

  •   类的加载的最终产品是位于内充中的Class对象
  •   Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口

Class是反射的入口。像一面镜子一样。

 

有两种类型的类加载器:

  1.Java虚拟机自带的加载器

  • 根类加载器(BootStrap)
  • 扩展类加载器(Extension)
  • 系统(应用)类加载器(System)

2.用户自定义的类加载器

  • java.lang.ClassLoader的子类
  • 用户可以定制类的加载方式

 

类的加载: 

 类加载器并不需要等到某个类被“首次主动使用”时候再加载它

 注:

  •   JVM规范允许类加载器在预料某个类将要被使用时就预先加载它。如果在预先加载的过程中遇到了.class文件确实或者存在错误,类加载器必须在程序首次主动使用该类时候才报告错误(LinkageaError错误)
  •   如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误

 

类的验证:

  类被加载后,就进入连接阶段。连接就是将已经读入到内存中的类的二进制数据合并到虚拟机的运行时的环境中去。

  

类的验证的内容:

  •   类文件的结构检查
  •   语义检查
  •   字节码验证
  •   二进制兼容性的验证

在准备阶段:

  

 

 

 

 初始化阶段:

 

 

 

 类的初始化步骤:

  •  假如这个类还没有被加载和连接,那就先进行加载和连接
  •  假如类存在直接父类,并且这个父类还没有被初始化,那就先初始直接父类
  •  假如类中存在初始化语句,那就依次执行这些初始化语句 

 

 

只有当程序访问的静态变量或静态方法确实在当前类或当前接口定义时,才可以认为是对类或接口的主动使用。

调用ClassLoader类的loadClass方法加载一个类,并不是对类的主动使用,不会导致类的初始化。

 

 

 

 

除了以上虚拟机自带的加载器外,用户还可以定制自己的类加载器。Java提供了抽象类java.lang.ClassLoader,所有用户自定义的类加载器都应该继承ClassLoader类

 

 

Android虚拟机ART 立即下载

相关推荐

钟世礼-深入解析ANDROID虚拟机(带书签完整高清版).pdf

Android系统从诞生到现在的短短几年时间里,凭借其易用性和开发的简洁性,赢得了广大开发者的支持。在整个Android系统中,Dalvik VM一直是贯穿从底层内核到高层应用开发的核心。本书循序渐进地讲解了Android虚拟机系统的基本知识,并剖析了其整个内存系统的进程和运作流程,并对虚拟机系统优化和异常处理的知识进行了详细讲解。本书几乎涵盖了Dalvik VM系统的所有主要内容,并且讲解方法通俗易懂,特别有利于读者学习并消化。本书适合Android初学者、Android底层开发人员、源代码分析人员和虚拟机开发人员学习,也可以作为大专院校相关专业师生的学习用书和培训学校的教材。

《深入理解 Android ART 虚拟机》笔记

另外,ART 还借助一种称之为 Lock Hierarchies 的方法来解决线程同步时经常出现的因为使用锁的顺序不一样导致死锁的问题(即线程应该按相同的顺序抢占互斥锁,比如先锁住互斥锁A,接着再锁住互斥锁B,否则极易出现死锁的情况)。很多人以为 Java 字节码编译成机器码后就能和那些 C/C++ 编译得到的机器码一样无所羁绊地直接在OS上运行了,殊不知在Java字节码编译为机器码的过程中,虚拟机会添加一些必要和特殊的指令,使得得到的机器码在运行过程中实际上离不开虚拟机的管控。笔者称这种双字节元素为。

川峰的博客 4184

深入理解jvm虚拟机

jvm虚拟机深入讲解,理解jvm的核心原理,是学习jvm的原理的很好教科书

虚拟机JVM,Dalvik,ART

一,Java内存区域 1,用一张图来表示内存区域 2,线程隔离的数据区(线程私有内存区域,线程之间互不影响) ①,程序计数器:是一块较小的内存空间,可以看成是当前线程所执行的字节码的行号指示器。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值为(Undefined)。此内存区域是唯一一个在Java虚拟

wang_yong_hui_1234的博客 1713

深入理解Android 邓凡平版

本资源带有目录的PDF电子书籍 深入理解Android 邓凡平版 需要的亲 请拿去 这个和正版书籍相匹配 文字清晰 可读性强

蓝桥杯STM32G431RBT6学习——GPIO

蓝桥杯STM32G431RBT6学习——GPIO

weixin_44098974的博客 2235

【底层机制】ART虚拟机深度解析:Android运行时的架构革命

ART(Android Runtime)是Android操作系统上的应用运行时环境,取代了最初的Dalvik虚拟机。从技术本质看,ART是一个基于AOT(Ahead-Of-Time)编译的托管代码执行环境,负责Android应用的字节码翻译、内存管理、线程调度和系统服务交互

沐怡旸的专栏 2110

CTFHUB------XSS反射型(WP)

文章目录前言XSS测试平台 前言 一开始我直接在上面写js脚本发现出错,最后发现只能通过下面的输入框来执行XSS测试,于是我们只能用XSS测试平台解决问题 XSS测试平台 注册一个XSS测试平台 这里随便填写 勾选默认模块就够了,点击下一步 这时会出现一个找个将代码复制 拼接到网站后缀name后面,点击send 这时平台会收到一个记录点开即可 得到flag ...

Y4tacker的博客 1万+

【JVM】深入理解虚拟机(上)

了解虚拟机到底是什么样的存在

阿杰 496

PID循迹控制算法

前言  让小车进行循迹最重要的是获取车相对于循迹线的位置,关于循迹模块的原理我已经在之前的一篇博客上讲过,如果大家没看过的话可以点此链接:PID循迹模块原理。 PID循迹原理简介 图1 循迹车寻线行走图示 图2 市场常见循迹传感器  PID循迹的原理我们大致可以用常识性思维去思考下,如图1所示为循迹车寻线行走图示,现在小车要按照中间那条黑线循迹行走,如果车头往左偏则需要控制方向盘让车往右转,车头往又偏则需要让车往左转。但是仅仅只有左转和右转的话,车一到左边就向右转,一到右边就向左转,则车会来回在线左右晃动

Dinvent的博客 7万+

在Kintex-7 FPGA上实现皮秒级时间测量:手把手教你搭建CARRY4进位链TDC(附源码与约束)

本文详细介绍了在Kintex-7 FPGA上利用CARRY4进位链实现皮秒级时间测量(TDC)的完整方案。从CARRY4的物理特性分析到硬件架构设计,再到校准方法与精度提升技巧,手把手教你构建测量精度达53ps的TDC系统,并附源码与约束文件,助力激光雷达、高能物理等精密计时应用开发。

weixin_42550052的博客 446

深入理解JVM虚拟机:从原理到实践

Java虚拟机(JVM)是运行Java字节码的虚拟计算机,它是Java语言跨平台特性的核心。JVM就像一个抽象的计算机,有自己的指令集和运行时内存区域,能够执行字节码文件(.class文件)。实现Java的跨平台特性(“一次编写,到处运行”)管理Java程序的内存执行垃圾回收提供字节码到机器码的转换确保程序的安全运行自定义类加载器通常需要继承类,并重写方法。示例:自定义类加载器// 类文件的存放路径@Overridetry {// 将类名转换为文件路径。

qq_44266569的博客 780

SAP-ABAP:SAP Open SQL 分页技术深度解析:语法、性能陷阱与最佳实践

SAP Open SQL 分页技术深度解析:语法、性能陷阱与最佳实践

baidu_35680696的博客 635

进入JVM的世界:《深入理解JVM虚拟机》-- 思维导图

进入JVM的世界:《深入理解JVM虚拟机》-- 思维导图之前一直都是零零散散的看了些JVM的知识,心想这样不行啊!于是便抽空看了一下这本神书,阅罢,醍醐灌顶、豁然开朗。真正的是知其然,更知其所以然。当然,看完了书,知识还不是自己的,只有留在自己的脑袋里面的,才是自己的。因此我整理了一份思维导图,希望自己有时间的时候,就多看看,多想想。巩固记忆。 大图地址:https://img2018.cnb...

weixin_30781631的博客 166

11-16 Fluent结果查看及后处理功能(做动画、监控点)

监控点、面及动画操作

zheaa的博客 1万+

深入jvm虚拟机第4版_读完了系列:深入理解Java虚拟机:JVM高。。。

读完了《深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)》,下面是感想:读完之后的感想是什么?最大的感受是增加了一些信心,颇有不明觉厉的感觉,以后代码出问题之后能有底气去处理,能知道大概往哪个方向去找。学习其他的JVM的语言时,能收放自如,举一反三,比如scala,kotlin增加底层的知识储备知道一些java面试题的答案背后的原理就这些,这本书我没有像以前一样细致的做笔记来罗列每一个细...

weixin_34357697的博客 2432

S7-200SMART PLC中进行MODBUS RTU通信的3种方法(1)

S7-200SMART PLC中进行MODBUS RTU通信的3种方法(1)

Robot_PLC_HMI_Automation 4241

我与《深入理解Java虚拟机-JVM高级特性与最佳实践》的故事

做为一名优秀的Java工程师,岂能不懂强大的Java Virtual Machine?巧逢周老师的《深入理解Java虚拟机-JVM高级特性与最佳实践》第三版问世,我也来分享下我与JVM的故事吧。 接下来,我按照时间顺序来对介绍下自己的JVM学习之路吧~ 学生时代: 在刚开始学习Java的时候,最开始有一个很模糊的概念,简单知道通过Java虚拟机可以实现一处编写,多处执行的功能。但是,因为是刚刚处...

冷血之心的博客 989

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【JVM】深入理解Java虚拟机

第一章 概述 1.1 JVM相关知识体系 1.2 JVM图例 图片出处 第二章Java内存区域与内存溢出异常 2.1 概述 2.2 运行时数据区域 2.2.1 程序计数器   线程私有,通过改变计数器的值选取下一条需要执行的字节码指令。执行本地方法(native)时计数器的值为空 2.2.2 Java虚拟机栈   线程私有,每个方法需要被执行时创建一个栈帧并压入栈顶,执行完毕出栈,调用其他方法时将其他方法的栈帧压入。   栈帧包括局部变量表、操作数栈、动态链接、方法返回地址、附加信息 2.2.2.1 局

dreambyday 4261

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

《深入理解JVM虚拟机》读书总结

今天,我终于把《深入理解JVM虚拟机》看完一遍了!内容很深,不过讲解的很透彻,可能需要我慢慢消化和吸收,等过一段时间再去多看几遍! 这本书大致分为五个部分十三个章节进行了讲解:第一部分:走近Java 这一部分只有第1章 第二部分:自动内存管理机制 这一部分包括第2~5章第三部分:虚拟机执行子系统 这......

笑看风云路的博客 4614

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

深入理解JVM虚拟机总结

本文是阅读周志明的《深入理解Java虚拟机》一书所做的总结,非常经典的一本书,内容很多话语除了自己总结外采用了书中的内容进行涵盖。以下的题目都是JVM虚拟机的面试题来源于https://blog.youkuaiyun.com/qq_34337272/article/details/80294328这篇博文,问题的回答都是自己找书中内容片段进行摘取总结,用来对自己翻阅这本书时留下笔记供以后复习时好翻阅...

一叶知秋hwb的博客 1057

深入理解java虚拟机jvm

Java虚拟机(JVM)是Java平台的核心组件,它负责将Java字节码转换成平台特定的机器指令,并在相应的硬件和操作系统上执行。

weixin_46229190的博客 1296

【JVM】深入理解JAVA之JVM虚拟机

深入理解Java之JVM虚拟机 JVM 一直都是面试中考察的重点 JVM(Java Virtual Machine):指以软件的方式模拟具有完整硬件系统功能、运行在一个完全隔离环境中的完整计算机系统,是物理机的软件实现 ...

JJJikerUPUP的博客 589
上一篇: IDEA光标类的操作
下一篇: 深入理解JVM虚拟机(总结篇)
Art&Code
博客等级 码龄7年 77粉丝 554原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值