后端技术面试38讲
李智慧
同程艺龙交通首席架构师,前Intel&阿里架构师,《大型网站技术架构》作者
立即订阅
3677 人已学习
课程目录
已更新 16 讲 / 共 38 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 掌握软件开发技术的第一性原理
免费
软件的基础原理 (8讲)
01丨程序运行原理:程序是如何运行又是如何崩溃的?
02丨数据结构原理:Hash表的时间复杂度为什么是O(1)?
03丨Java虚拟机原理:JVM为什么被称为机器(machine)?
04丨网络编程原理:一个字符的互联网之旅
05丨文件系统原理:如何用1分钟遍历一个100TB的文件?
06丨数据库原理:为什么PrepareStatement性能更好更安全?
07丨编程语言原理:面向对象编程是编程的终极形态吗?
答疑丨Java Web程序的运行时环境到底是怎样的?
软件的设计原理 (6讲)
08丨软件设计的方法论:软件为什么要建模?
09丨软件设计实践:如何使用UML完成一个设计文档?
10 | 软件设计的目的:糟糕的程序员比优秀的程序员差在哪里?
11丨软件设计的开闭原则:如何不修改代码却能实现需求变更?
12 | 软件设计的依赖倒置原则:如何不依赖代码却可以复用它的功能?
13丨软件设计的里氏替换原则:正方形可以继承长方形吗?
不定期加餐 (1讲)
加餐 | 软件设计文档示例模板
后端技术面试38讲
登录|注册

03丨Java虚拟机原理:JVM为什么被称为机器(machine)?

李智慧 2019-11-22
人们常说,Java 是一种跨平台的语言,这意味着 Java 开发出来的程序经过编译后,可以在 Linux 上运行,也可以在 Windows 上运行;可以在 PC、服务器上运行,也可以在手机上运行;可以在 X86 的 CPU 上运行,也可以在 ARM 的 CPU 上运行。
因为不同操作系统,特别是不同 CPU 架构,是不可能执行相同的指令的。而 Java 之所以有这种神奇的特性,就是因为 Java 编译的字节码文件不是直接在底层的系统平台上运行的,而是在 Java 虚拟机 JVM 上运行,JVM 屏蔽了底层系统的不同,为 Java 字节码文件构造了一个统一的运行环境。JVM 本质上也是一个应用程序,启动以后加载执行 Java 字节码文件。JVM 的全称是 Java Virtual Machine,你有没有想过,这样一个程序为什么被称为机器(Machine)呢?
其实,如果回答了这个问题,也就了解了 JVM 的底层构造了。这样在进行 Java 开发的时候,如果遇到各种问题,都可以思考一下在 JVM 层面是如何的?然后进一步查找资料、分析问题,直至真正地解决问题。

JVM 的组成构造

要想知道这个问题的答案,我们首先需要了解 JVM 的构造。JVM 主要由类加载器、运行时数据区、执行引擎三个部分组成。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《后端技术面试38讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(16)

  • 幸福来敲门
    老师,内存溢出和内存泄漏有什么区别,以java为例??

    作者回复: 内存溢出是说程序需要申请的内存超过了JVM当前可以分配的最大内存,溢出。

    内存泄漏是说期望被回收的内存对象没有被回收,泄漏。

    内存泄漏持续发生,很可能引起内存溢出。

    2019-11-22
    1
    17
  • 乘坐Tornado的线程魔法师
    存活对象从From区复制到To区之后,在交换名称之前,是不是要把From区的那些不存活对象全部回收?(保证交换名字之后,To区永远是空白的)

    作者回复: 内存空间只需要标记是空闲就可以,交换以后To区就已经是空白的了。

    2019-11-22
    3
  • [耶]友超
    老师,好强大的内功
    2019-11-22
    1
    3
  • Solomon
    老师你好
    1.为什么新生代要设置3个区域呢?只有from和to不行吗?
    2.多线程执行的时候,栈帧在栈上如何分配空间的,是分多个java栈吗?

    作者回复: 1 因为一个对象在from和to之间多次拷贝,然后才会放入老年代。
    2 每个线程有自己的线程栈。

    2019-11-23
    2
    2
  • KL3
    请问老师,关于类加载,对象方法和类方法都是放在方法区吗?

    作者回复: 可执行的代码都在方法区。

    对象是类的实例,实例变量在堆中,同一个类的所有对象实例的方法只有一份,在方法区。

    2019-11-22
    3
    2
  • 老男孩
    虽然之前学习过相关的知识,老师讲的不敢说是最全面的,但是非常易于理解,我对jvm相关知识又有了新的认识!受益匪浅!
    1)如果能把类加载机制说的更详细一点就更好了。因为以前我遇到过一个问题,就是tomcat启动后无法访问,一看日志报了一个PermGen空间不足的error,后来重新设置了一下就好了。原因可能是加了很多依赖jar包导致PermGen空间不足了。当时没有再多想。加载类信息以及静态常量是启动的时候一把加载进来?还是执行的过程中用到哪个类的时候再加载?如果不是一把加载进来,为什么tomcat启动后就报空间不足?
    2)关于集合容器中元素导致的内存泄露问题,看了老师的文章我觉得如果map在方法中定义应该问题不大,但如果map是类的属性或者是一个静态属性的话就要小心了。不用元素一定要记得remove,或者可以使用弱引用的集合容器。
    2019-11-22
    1
    2
  • 我爱布丁
    老师,第一讲中谈到当操作系统载入编译后程序时,会在内存中建立进程,划分代码段,堆,栈等。那么当操作系统运行JAVA虚拟机加载类文件时,在虚拟机中的Java堆,栈是否会直接map到JAVA虚拟机进程的堆,栈呢?从操作系统看一个JAVA虚拟机进程,和一个普通的编译后程序进程结构上有区别吗?

    作者回复: 虚拟机内部的堆和栈不会map到操作系统的堆和栈,这样才能跨平台。

    操作系统看JVM就是一个普通进程。

    2019-11-22
    2
    2
  • y欧尼酱
    老师能多讲讲类加载吗,这儿只知道jvm加载class字节码,在深入就不懂了,谢谢老师。
    2019-11-22
    1
  • 乘坐Tornado的线程魔法师
    操作系统处理线程栈这个场景是不是可以想象成,高并发场景下,每一个请求都要压入操作系统的线程栈,请求返回后,执行这个请求的线程才能从操作系统的线程栈中出栈?

    作者回复: 每个线程有自己的线程栈,用来管理方法的局部变量。而线程本身的管理不需要用栈。

    事实上,线程是使用线程池管理的,请求到来,就到线程池中申请分配一个空闲线程,请求处理完,线程放回到空闲线程池中。

    2019-11-22
    1
  • 乘坐Tornado的线程魔法师
    老师好,有关JVM运行前的编译过程,请问HotSpot编译器和IDEA编译器的区别是什么?
    2019-11-22
    1
  • Caliven
    看完第一节在看这一节有种恍然大悟的感觉
    2019-12-14
  • Paul Shan
    Java虚拟机是操作系统之上的操作系统:
    操作系统是加载可执行文件执行,JVM是加载class文件执行。操作系统可以调度进程和线程,JVM主要调度线程。操作系统有堆栈作为存储,JVM也有堆栈,而且还可以回收堆中的内存。另外一个角度讲操作系统是jvm的基础,jvm是操作系统运行的众多进程之一,jvm屏蔽了操作系统的底层细节,才得以跨平台的
    2019-12-05
  • 探索无止境
    老师,那老年代和年轻代各自用什么样的垃圾回收算法和垃圾回收器?
    2019-12-02
    1
  • vega
    1.8之后好像xms参数不能用了。似乎g1之后还有一两个新的垃圾回收器吧
    2019-12-01
  • miracle
    虽然这个对象被放置在堆中,但是这个对象不会被其他线程访问到,也是线程安全的。

    请问下,多个线程都可以访问这个方法,进而可以操作堆中的对象,为什么是线程安全的

    作者回复: 每个线程都可以访问这个方法,如果在这个方法内创建一个对象,那么就意味着“每个”线程都会“自己”创建一个对象。线程之间不会访问彼此的对象。

    2019-11-23
    3
  • 尹宗昌
    老师,之前看到,MySQL connector-j 驱动在特定模式下(useCompression=true)的内存泄漏问题。能简单提个思路,这样也能循序渐进
    2019-11-22
收起评论
16
返回
顶部