| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 为什么面试总是会被问到JVM内存区域? -> 正文阅读 |
|
[Java知识库]为什么面试总是会被问到JVM内存区域? |
1.JVM概念**JVM**(Java Virtual Machine的简称),意为Java虚拟机虚拟机:指通过软件模拟的具有完整硬件功能的,运行在一个完全隔离的环境中的完整的计算机系统,常见的虚拟机有:JVM, VMwave, Virtual Box。 JVM和其他两个虚拟机的区别:
JVM是一台被定制过的现实当中不存在的计算机。 2.为什么要有JVM呢因为Java有一个很重要的特性——跨平台也就是“一次编写,到处运行”,也就是编写一个程序,可以在Windows,Linux,Mac等系统上直接运行,我们都知道不同的计算机有不同的硬件结构(CPU的体系架构不同),也有不同的操作系统,操作系统提供的API也不一样,而JVM就是屏蔽不同计算机上软硬件的差异,也就是代码只需要对虚拟机负责就OK,也就达到了我们的跨平台的目的。JVM也不仅仅是一个程序,不同的系统都会对应一个JVM的版本(如:Windows的JVM是一个版本,Linux的JVM也是一个版本),但是不管是那个版本的JVM,都懂Java语言。 这也就说明为什么我们在官网上面下载的同一个 Tomcat 压缩包,既能在Windows上运行,也能够在Linux上运行,都是靠JVM把其中的差异给屏蔽掉了。 注:JVM发展到现在,不仅仅是为了跨平台,而是已经打造成了一个生态圈,大量的程序/库/编程语言都是基于JVM的,但是对于一个编程语言来说,实现编译器(就是把源代码翻译成可执行指令),直接翻译成机器指令native指令,比较复杂,考虑到系统的差异,CPU的差异,那么工作量也就大了,干脆就将编程语言直接翻译成JVM能够之别的字节码,由JVM去考虑软硬件之间的差异,大大降低工作量。 JVM有没有什么缺点呢? 答:当然有,因为没有什么东西是完美无瑕的,在一个程序中,要先将编程语言翻译成JVM能够识别的字节码,然后再不同的系统中,JVM在屏蔽软硬件的差异再去翻译成不同系统能够识别的程序,那么效率肯定会受到影响。(注:虽然虚拟机能够影响到一定的效率,但是在真正的商业项目中,性能瓶颈往往不是编程语言自身带来的,更主要的瓶颈是网络IO/数据库/磁盘IO/复杂的CPU密集计算……)。 3.JVM中的内存区域划分JVM运行时数据区 JVM会在执行Java程序的过程中把它管理的内存划分为若干个不同的数据区域。这些数据区域各有各的用处,各有各的创建与销毁时间,有的区域随着JVM进程的启动而存在,有的区域则依赖用户线程的启动和结束而创建与销毁。一般来说,JVM所管理的内存将会包含以下几个运行时数据区域
JVM内存模型(JDK1.8) 3.1.程序计数器(线程私有)程序计数器是一块比较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。
程序计数器内存区域是唯一一个在JVM规范中没有规定任何OOM清空的区域 什么是线程私有: 由于JVM的多线程是通过线程轮流切换分配处理器执行时间的方式来实现的,因此在任何一个确定的时刻,一个处理器(多多核处理器则指的是一个内核)都只会执行一条线程中的指令,因此为了切换线程后能恢复到正确的执行位置,每条线程都需要独立的程序计数器,各条线程之间计数器互不影响,独立存储。类似这类区域成为“线程私有”。 3.2.java虚拟机栈(线程私有)相对于基于寄存器的运行环境,JVM是基于栈结构的运行环境。栈结构移植性更好,可控性更强。 虚拟机栈描述的是Java方法执行的内存模型: 每个方法执行的同时都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息,每一个方法从调用直至执行完成的过程,就对应一个栈帧在虚拟机栈中入栈和出栈的过程,声明周期和线程相同。
在执行引擎运行时,所有指令都只能针对当前栈帧操作,StackOverflowError表示请求的栈溢出,导致内存耗尽,通常出现在递归方法。 **局部变量表:**局部变量表的创建是在方法被执行的时候,随栈帧创建而创建。存放了编译器可知的各种基本数据类型(八大基本数据类型),对象引用。局部变量表所需要的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量表空间是完全确定的,在执行期间不会改变局部变量表大小。 此区域会产生两种异常:
Java虚拟机栈也是线程私有的,每个线程都有各自的Java虚拟机栈,而且随着线程的创建而创建,随线程的死亡而死亡。 注意: 3.3.本地方法栈(线程私有)本地方法栈:与虚拟机的作用完全一样,区别在于本地方法栈为虚拟机使用的Native(本地)方法服务,而虚拟机栈为JVM的java方法服务。 在JVM内存布局中,也是线程对象私有的,但是虚拟机栈“主内”,而本地方法栈“主外”。 当大量本地方法出现时,势必会削弱JVM对系统的控制力,因为它的出错信息都比较黑盒。对于内存不足的情况,本地方法栈还是会拋出native heap OutOfMemory。 3.4.java堆(线程共享)
3.5.方法区(线程共享)方法区:与java堆一样,是各个线程共享的内存区域,用于存储已经被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,在JDK8以前的HotSpoot虚拟机中,方法区也被称为“永久代”(JDK8已经被元空间取代)
注:方法区同堆一样,允许固定大小,可扩展大小,还允许不实现GC,但是内存空间分配无法达到需求的时候,也会抛出OOM异常 举例说明:
3.6.运行时常量池(方法区的一部分).java文件被编译之后生成的.class文件中除了包含:类的版本、字段、方法、接口等描述信息外,还有一项就是常量池。运行时常量池是方法区的一部分,存放字面量与符号引用。 字面量:字符串(JDK1.7后移动到堆中),final常量,基本数据类型的值。 运行时常量池可能会抛出的异常:
4.常见面试题4.1.谈谈基础数据类型和引用类型之间的区别?答:如果是基础数据类型(如:int double……),当你创建这个静态变量的时候,此时在内存就立即创建了一个空间来保存这个变量,只不过这个变量是在栈上还是在堆上,取决于这个变量是局部变量还是成员变量,如果是引用类型,那么他本质上存的是地址(就是一个整数),所谓地址就是内存按照字节为单位分成了很多小房间,每个房间大小为1字节,每个房间都有编号(从0开始计算,依次累加),对应的房间号就是地址,只不过地址一般都写作十六进制来表示4.2.如何理解引用和对象?答:引用保存了对象所在的地址,对象才是组织数据的本体(把对象假设成一个房间,房间里面有各种设施;引用就是开启房间的钥匙) 例如: new Test(); new出来的东西是对象,是在堆上创建的这个内存区域,这个才是对象的本体(真正存储数据的部分) Test t = new Test(); new返回的结果 t 是在堆的内存区域的地址,这个地址要交给一个引用类型来持有 t.num 根据 t 存储的地址,找到堆上对应的房间,进而找到房间中的设施(如果 num 是基础类型,就直接找到值了;如果num是引用类型,还需要根据引用中存储的房间号,继续往下找)4.3.局部变量/成员变量/静态成员变量所对应的内存区域?答:局部变量对应的内存区域是在栈上; 成员变量对应的内存区域是在堆上; 静态成员变量对应的内存区域在方法区,因为这个变量也可能是引用类型,只是说这个引用自身,是在方法区,对应的对象仍然是在堆上。(例如:public static String str = new String("hello"));4.4.递归方法执行过程如何理解?答:注意栈的变化,每次递归,都会创建新的栈帧,同一个名字的变量可能会在多个栈帧中出现,(虽然同名,但是不是同一个变量),每个方法执行完毕,当前栈帧就被销毁了,进而回到上一层调用位置上继续往下执行。 [栈帧的出栈和入栈可以参考](https://blog.csdn.net/weixin_44663675/article/details/107014923?ops_request_misc=&request_id=&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2~all~es_rank~default-2-107014923.pc_search_all_es&utm_term=%E9%80%92%E5%BD%92%E6%96%B9%E6%B3%95%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3jvm&spm=1018.2226.3001.4187)如:递归就 n 的阶乘
当我们debug的时候 4.5.普通方法和static方法之间的区别?答:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 5:28:37- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |