面试常问问题:
1、请你谈谈你对JVM的理解。谈谈java8虚拟机的变化,做了什么更新。
2、什么是OOM,什么是栈溢出StackOverFlowerError?怎么分析?
3、JVM常用的调优参数有哪些?
4、内存快照如何抓取?怎么分析Dump文件?
5、谈谈JVM中你对类加载器的认识
知识点整理
1、JVM的位置
JVM(Java 虚拟机)运行在操作系统上,可以跑java程序
硬件--> 操作系统--> JVM
2、JVM的体系结构
JVM调优基本在堆调优
3、类加载器
作用:加载.class文件
类是模板,对象是具体的。
4、双亲委派机制
类加载器收到类加载请求;将这个请求向上委托到父类加载器去完成,一直向上委托;启用类加载器检查是否能够加载当前请求,能加载就执行当前请求,否则就通知子类加载器进行加载;如果都不能执行,则抛出异常。
5、沙箱安全机制
java安全模型的核心就是java沙箱。将java代码限定在虚拟机(JVM)的运行范围中。主要限制系统资源
6、Native
凡是带有native关键字的,说明java范围作用达不到了,回去调用c语言的库。
JNI接口:作用是扩展java的使用,融合不同语言为java所用。当时为了融合c语言和c++,于是在内存中开辟了一块标记区域:Native Method stack登记native方法
7、PC寄存器
8、方法区
9、栈
桶 先进后 出
队列 管道,先进先出
10、三种JVM
sun公司的hotsop
BEA
IBE
11、堆
Heap,一个jvm只有一个堆内存,堆内存的大小是可以调节的
类加载器读取了类文件后,一般会把类,方法,常量。变量放到堆中
12、新生区、老年区
新生区 new
类诞生和成长的地方
伊甸园区new
幸存区0区 幸存区1区
(真理:经过研究,99%的对象都是临时对象)
垃圾回收:轻量级回收、重量级回收Full GC;GC垃圾回收主要是在新生区和养老区
养老区
永久区 :这个区域常驻内存的,常用来存放jdk自身携带的class对象,Interface元数据,存储的是java运行时的一些环境或类信息,这个区域不存在垃圾回收,关闭虚拟机就会释放这个区域的内存
一个启动类,加载‘了大量的第三方jar包,Tomcat部署了太多的应用,大量动态生成的的反射类不断的被加载,内存满了就就会出现OOM
13、永久区
OOM 内存用完了超出了 堆溢出,堆内存不够
14、堆内存调优
服务器内存调整
可以使用工具JProfiler进行定位,查看Dump内存反馈文档具体定位到对象和具体行数位置
15、GC
自动垃圾回收,不能手动,但是可以提醒
JVM在进行GC时,并不是对这三个区域统一回收,大部分时候回收都是新生代
幸存区(0 from ,1 to)0和1区会交换,谁的空间空就是to的那一个(每次GC都会将新生区的对象移到幸存区中,一旦新生区被GC后就都会是空的;默认当一个对象经历了15次GC都还活着(最大任期时间)就到养老区)
轻量级GC(普通GC),重GC(全局GC)
问题1
问题2
问题3 GC的算法有哪些? 怎么用的,都有什么区别
1标记清除法
2标记清理(标记压缩)
3复制算法
4引用计数器(计数器本身有消耗,效率不高)
给每个对象用计数,用了几次标记几,不用了就被清除了
总结
内存效率 复制算法>标记清除算法>标记压缩算法(时间复杂度)
内存整齐度:复制算法> 标记压缩算法 >标记清楚算法
内存利用率:标记压缩算法 >标记清除算法 >复制算法
没有一种最好的算法,按实际使用场景用最合适的算法
17、总结GC也被称为分代收集算法
年轻代:存活率低,复制算法
老年代:区域大,存活率高,标记清除(内存碎片不是太多)+标记压缩 混合实现