• 浅谈JVM


    操作系统内核是至高无尚的内功心法,只有掌握了内功,学习其他的武功才会轻而易举。

    现在我们来谈谈java。JVM其实是操作系统中运行的进程,JVM有操作系统进程的所有共性,但是它却不是一个普通的进程,它有它特殊的地方,它将许多本来属于操作系统管理范畴的东西,移植到了JVM内部,减少系统调用的开销。

    1.在普通程序(如C++)中,如果new一个对象,会产生一个系统调用,由操作系统线程根据对象的大小分配好空间后返回;若要释放对象,也需要detele产生一个系统调用,通知操作系统 对象所占用的空间已经可以回收。但是JVM堆中,只需要在最开始进行一次系统调用,向操作系统申请一整段区域作为java程序的堆,之后创建和销毁对象都不需要再进行系统调用,而是直接由JVM在内部按需分配,这样大大减少了系统调用的开销。同时C++需要明确调用delete进行内存回收,如果程序员忘了就很容易造成内存泄露,然而在JVM中有垃圾回收器负责回收内存。

    2.应用程序通常不直接和内核内存打交道,内核内存由操作系统进行管理和使用;不过随着Linux对性能的关注及改进,一些新的特性使得应用程序(JVM)可以使用内核内存,或者是映射到内核空间。Java NIO正是在这种背景下诞生的。在java NIO中,为了减少读写IO系统调用的开销,使用到了内核的内存。当应用程序想将磁盘文件的数据发送网卡,不需要先进行系统调用读入用户空间,再系统调用输出到内核空间,而是直接在内核空间就完成整个操作了,大大减少了系统调用的次数

    我们可以把JVM看成一台虚拟的机器,这台机器可以按需加载可执行二进制文件(字节码文件),然后由虚拟机执行引擎解释执行字节码,将其翻译成cpu可以识别的指令。在jvm的逻辑地址空间中,有方法区(用来存放可执行文件),堆(用于存放对象和数组,jvm垃圾回收器动态分配和回收该区域的内存空间),栈(保存线程的方法调用关系,数据),常量池(存放常量)等。因此,一个Java虚拟机实例在运行过程中有三个子系统来保障它的正常运行,分别是类加载器子系统, 执行引擎子系统和垃圾收集子系统。字节码文件相当于食物,类加载器相当于嘴,执行引擎相当于胃,垃圾回收器相当于排泄系统。    

    执行引擎包括字节码解释器和JIT(just-in-time)及时编译器,解释器将字节码文件一行一行边解释边执行(解释成cpu能识别的指令),而JIT编译器则是将整个字节码文件编译成cpu能够识别的指令,也就是在执行前全部被翻译为机器码,这样做的好处是将热点代码缓存起来,下次使用的时候cpu直接执行,而不用再逐行解释。

    为什么要引入java虚拟机呢?是为了让java能够跨平台。

    在c语言中,只需要gcc将源代码文件编译后,操作系统就可以识别该执行文件了。但是在java中,当编译成字节码文件后,操作系统是无法直接运行的,因为不识别,所以引入了JVM,由JVM负责加载字节码文件,然后在JVM中解释执行,将其翻译成cpu可以识别的指令。这样一来,只需要让JVM平台相关就可以了,不同操作系统安装对应版本的JVM,然后由JVM负责和操作系统打交道,从而让java代码变成平台无关的。只需要一次编译,就能够到处执行。

    java HelloWorld,该命令会首先启动一个虚拟机进程,将HelloWorld的可执行文件加载到该进程的地址空间,然后解释执行。在Java虚拟机执行过程中,只有当需要一个类的时候,才会调用类加载器来加载这个类,并不会在开始运行时加载所有的类。这种类的动态加载机制造就了java的多态。

  • 相关阅读:
    Java中数组遍历
    数组常见异常
    数组的访问
    Java中数组的定义方式
    Java中数组的概念与特点
    node爬虫技术初探
    node相关内容
    vs code快捷键
    vue 入门开发
    es6 常见用法
  • 原文地址:https://www.cnblogs.com/misscai/p/9696647.html
Copyright © 2020-2023  润新知