10 StackOverFlow与OOM的区别?分别发生在什么时候,JVM栈中存储的是什么,堆存储的是什么?(美团)
这道题想考察什么?
JVM内存
考察的知识点
内存泄露,JVM运行时数据区
考生应该如何回答
StackOverFlow是栈空间不足出现的,主要是单个线程运行过程中调用方法过多或是方法递归操作时申请的栈帧使用存储空间超出了单个栈申请的存储空间。
OOM主要是堆区申请的内存空间不够用时出现,比如单次申请大对象超出了堆中连续的可用空间。
栈中主要是用于存放程序运行过程中需要使用的变量,引用和临时数据,堆中主要存储程序中申请的对象空间。
11 StringBuffer与StringBuilder在进行字符串操作时的效率(字节跳动)
这道题想考察什么?
在开发中需要进行字符串操作时如何合理利用StringBuffer与StringBuilder
考察的知识点
字符串工具类
考生应该如何回答
当对字符串进行修改的时候,使用 StringBuffer 和 StringBuilder 能够多次的修改,并且不产生新的未使用字符串对象。
String在进行字符串操作时,每次操作都会new StringBuilder,如进行字符串拼接:
String result = "Hello ";
for(int i = 0; i < 100; i++){
result += "Hello ";
}
上述代码等价于:
String result = "Hello ";
for(int i = 0; i < 100; i++){
result = new StringBuilder().append(result).append("Hello ");
}
可以看到每次循环都需要创建一个StringBuilder 使用其append
方法完成字符串拼接。频繁创建与回收对象会导致 "内存抖动" 问题,引发程序卡顿甚至OOM。
因此相对直接使用String进行字符串操作,应将代码优化为:
StringBuilder result = new StringBuilder("Hello ");
for(int i = 0; i < 100; i++){
result.append("Hello ");
}
而StringBuffer与StringBuilder的功能与实现原理一致,两者的区别在于,StringBuffer中的方法都被关键字synchronized
声明,这意味着其是线程安全的,但是因为每次执行方法都需要获取锁,因此效率比StringBuilder稍低。
在涉及到多线程环境下操作字符串时,应该使用StringBuffer;否则应该选择StringBuilder效率更高。
12 JVM DVM ART的区别
这道题想考察什么?
Android虚拟机与Java虚拟机的差异
考察的知识点
- JVM虚拟的基本知识
- DVM虚拟机的基本知识
- ART虚拟机的基本知识
考生应该如何回答
JVM
JVM是基于栈的虚拟机,对于基于栈的虚拟机来说,每一个运行时的线程,都有一个独立的栈。栈中记录了方法调用的历史,每有一次方法调用,栈中便会多一个栈桢。最顶部的栈桢称作当前栈桢,其代表着当前执行的方法。基于栈的虚拟机通过操作数栈进行所有操作。
栈帧.png在JVM中执行字节码,将
int a = 1;
int b = 2;
int c = a + b;
编译为字节码,得到的指令为:
ICONST_1 #将int类型常量1压入操作数栈
ISTORE 0 #将栈顶int类型值存入局部变量0
ICONST_2
ISTORE 1
ILOAD 0 #从局部变量表加载0:int类型数据
ILOAD 1
IADD #执行int类型加法
ISTORE 2
数据会不断在操作数栈与局部变量表之间移动。
Dalvik
Dalvik虚拟机( Dalvik Virtual Machine ),简称Dalvik VM或者DVM。DVM是Google专门为Android平台开发的虚拟机,它运行在Android运行时库中。
与JVM区别
基于的架构不同
DVM是基于寄存器的虚拟机,并没有JVM栈帧中的操作数栈,但是有很多虚拟寄存器。其实和操作数栈相同,这些寄存器也存放在运行时栈中,本质上就是一个数组。与JVM相似,在Dalvik VM中每个线程都有自己的PC和调用栈,方法调用的活动记录以帧为单位保存在调用栈上。
与JVM版相比,Dalvik无需从栈中读写数据,所需的指令更少,数据也不再需要频繁的移动。
#int a = 1
const/4 v0, #int 1 // #1
#int b = 2
const/4 v1, #int 2 // #2
#int c = a + b
add-int v2, v0, v1
执行的字节码不同
- 在Java中,Java类会被编译成一个或多个.class文件,打包成jar文件,而后JVM会通过相应的.class文件和jar文件获取相应的字节码。
- DVM会用dx工具将所有的.class文件或者jar文件转换为一个.dex文件,然后DVM会从该.dex文件读取指令和数据。
.jar文件在中包含多个.class文件,每个.class文件里面包含了该类的常量池、类信息、属性等等。当JVM加载该.jar文件的时候,会加载里面的所有的.class文件,JVM的这种加载方式很慢,对于内存有限的移动设备并不合适。
而.dex文件中也包含很多类信息,但是dex将多个类信息整合在一起了,多个类复用常量池等区域。
ART
ART(Android Runtime)是Android 4.4发布的,用来替换Dalvik虚拟,Android 4.4默认采用的还是DVM,系统会提供一个选项来开启ART。在Android 5.0时,默认采用ART。
与DVM的区别
Dalvik下应用在安装的过程,会执行一次优化,将dex字节码进行优化生成odex文件。
ART能够兼容Dalvik中的字节码执行。但是ART 引入了预先编译机制(Ahead Of Time),在Android4.4到Android 7.0以下的设备中安装应用时,ART 会使用 dex2oat 程序编译应用,将应用中dex编译成本地机器码。但是此过程会导致应用安装变慢。
因此,从Android N(Android 7.0)开始,ART 混合使用AOT、JIT与解释执行:
1、最初安装应用时不进行任何 AOT 编译(避免安装过慢),运行过程中解释执行,对经常执行的方法进行JIT,经过 JIT 编译的方法将会记录到Profile配置文件中。
2、当设备闲置和充电时,编译守护进程会运行,根据Profile文件对常用代码进行 AOT 编译。待下次运行时直接使用。
最后
整理不易,白嫖太易,关注哇哇,以上均可分享哦~
网友评论