飞越面试官(三)--JVM
大家好!我是本公众号唯一官方指定没头屑的小便--怕屁林。
JVM,全称Java Virtual Machine,作为执行Java程序的容器,几乎代理了Java内存与服务器内存的交互,可以说是程序拥有自己专属的内存的一样,这样方便了Java程序在各个操作系统上运行,因为各个系统安装了JVM即可。有意思的是,现在使用JVM的不止Java,也有其他语言可以运行在这之上。
第一道常规问题几乎就是,说下JVM里面有什么?就是堆、方法区/元空间/直接内存,不同JDK版本这个不同,然后线程私有的就是程序计数器、虚拟机栈、本地方法栈。问过JVM里面哪个部位不会发生OOM,其实就是程序计数器不会发生,它的作用也是保存下条指令、分支,循环,跳转、异常处理,线程恢复的位置。创建对象占用的内存就是通过堆来分配的,包括对象和数组的创建,同时也是垃圾收集器的管理区域,而且JDK7之后也把字符串常量池放到了这里来。线程私有的虚拟机栈和本地方法栈则各自保存执行方法和native方法中局部变量,操作数栈,动态链接,方法出入口信息。

堆里面产生的对象越来越多肯定是不行的,到了一定程度的时候就需要进行垃圾回收。堆里面垃圾回收区域分为eden、from survivor、tosurvivor,或者说S0和S1、还有old老年区。这里是一个分代回收的方式,为对象分配内存会在eden区进行,当eden区大到装不下的时候,就会发生一次minor gc,将eden区域中还能活的对象内存复制到S0,下一次再gc的时候,会将eden和S0的存活对象复制到S1,再下次就是将eden和S1的存活对象复制到S0,周而复始,当复制次数超过默认的15次的时候,就会进行old老年区,此外大对象是直接进入老年区的。当老年区也达到一定大小的时候,会发生full gc。full gc要比minor gc慢很多,所以要尽量减少full gc,例如老年区设置大一点。也有建议是full gc之前进行一次minor gc,因为老年区对象中有很多引用来自年轻代,一次minor gc可以整理一下,从而高效执行full gc。
如何判断一个对象是可以回收的呢?第一个引用计数法,就是多了一个引用就加一,少了一个引用就减一,零的时候就是没有引用了,但是这样如果两个对象互相引用,那么就永远不能回收了。第二个可达性分析法,一些虚拟机栈中引用的对象、方法区类静态属性引用的对象-方法区常量池引用的对象、本地方法栈JNI引用的对象作为一个根节点,查出它们引用的对象,构造出它们的引用树,不在这些树上的对象就可以回收了。
知道哪些垃圾收集器吗?收集器是围绕复制、标记-清除、标记-整理这几个算法展开的。像新生代的垃圾收集器就有serial单线程回收、ParNew多线程回收,Parallel Scavenge注重吞吐量的并发垃圾回收。老年代垃圾回收有serial old、Parallel old、CMS并发标记清除,以获取最短回收停顿时间为目标的收集器,基本实现垃圾回收和用户线程同时工作,整堆收集器有G1,一个维护了回收优先级列表的收集器,面向服务器的。

有没有过JVM调优经历呢?肯定有的,一般而言,项目上线后,堆大小是不完全确定的,需要调整,使用参数-Xms初始化堆大小和-Xmx堆最大多少,很多配置是这两个参数保持一样,建议是物理内存的二分之一和三分之一,-Xmn则是设置年轻代的大小,像之前上线了一个项目因为忙着服务器前前后后的软件安装,没有考虑这些参数,后面查看GC的情况时,发现minor gc和full gc次数不少,再查看堆分区大小的设置,的确默认的都比较小,是导致频繁gc的根源,接着修改为物理内存的二分之一,就没有再发生gc了,这个情况或许还能把堆调小一点。-XX:NewRatio是设置新生代和老年代的比例,-XX:SurvivorRatio则是设置eden和surivior的比例。-XX:+HeapDumpOnOutOfMemoryError则可以保存发生OOM时的实际数据。对于设置什么样的收集器,则应该查看文档来设置。

怎么看查看应用的JVM信息?首先使用JPS命令,得到应用的PID,就可以用jinfo -flag PID查看参数设置情况,使用jmap -heap PID查看分代配置情况,使用jstat -gcutil PID则可以查看gc发生的统计信息。

在编程的时候,会见到每个对象都有finalize()方法,调用它意味着什么?可达性分析中,分析出对象可以回收,如果类有覆盖finalize方法,会放到一个F-Queue中,虚拟机触发一个线程去执行,但不会承诺一直等待它运行完避免死锁从而内存回收系统崩溃,GC对处于F-Queue中的对象进行第二次被标记,这时该对象将会被移除“即将回收”集合,等待回收。
其实JVM分配内存,涉及到了对象的创建过程,对象创建的过程包括类加载检查、分配内存、初始化零值、设置对象头、执行init方法。类加载检查就是检查这个类信息有没有加载到方法区或者元空间中,设置对象头则是一些hascode、gc分代年龄等。其中分配内存涉及到在堆上面寻找空闲空间,方式有"指针碰撞"和"空闲列表",指针碰撞是维护一个指针,指向空闲和非空闲区域,对象需要多少内存则可以通过滑动指针类分配。空闲列表则是维护一个记录空闲位置的列表,需要多大的内存在列表上一查就清楚了。采用哪种方式取决于内存是否规整。分配内存也涉及并发线程安全问题,解决办法是在eden区上划分很多的TLAB小区,分配内存在TLAB上分配各不打扰,如果TLAB分配不下或都要用完了,则走CAS解决冲突分配内存。
第一版Java面试知识点汇总下载(有不少错别字和没更新的):https://pan.baidu.com/s/1MxKXIZtoBd57pTwTIDyrgA 提取码: 3arb。
相关阅读:
个人公众号,关注可第一时间获取最新文章!

飞越面试官(三)--JVM的更多相关文章
- 飞越面试官(二)--JUC
大家好!我是本号唯一官方指定没头屑的小便--怕屁林. JUC是什么东西?我相信很多经验尚浅的小伙伴部分都会为之一懵,我也是,三个字母都会读,连在一起就不知道在说什么,其实如果把它的全称写出来,“jav ...
- 飞越面试官(一)--Java基础
大家好!我是本公众号唯一官方指定没头屑的小便--怕屁林. 众所周知,现场面试(包括视频面试)多数时候是没有白板,也就是说,对于你的知识点.项目经验.过往经历和个人介绍等等,都是靠一张嘴.所以考虑到这个 ...
- 面试高峰期,如何应对面试官的jvm刁难,特写一篇jvm面经(第一部)
已经进入三月份,正所谓金三银四,正是一年最好的招聘期,想必我的公号粉丝们一定有不少想要跳槽的吧,哈哈,/**偷偷告诉你们其实小编也准备跳槽*/(我要加个注释,被老板知道可就完蛋了),说到面试,想必大家 ...
- 面试官:JVM锁优化都优化了啥?
从JDK1.6开始,JVM对锁进行了各种优化,目的就是为了在线程间更高效的共享数据和解决互斥同步的问题.从锁优化的话题开始,可以引申出很多考点面试题,比如锁优化的技术.各优化技术的细节.CAS实现原理 ...
- 【对线面试官】CountDownLatch和CyclicBarrier的区别
<对线面试官>系列目前已经连载31篇啦,这是一个讲人话面试系列 [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 &am ...
- 【对线面试官】Kafka基础入门
<对线面试官>系列目前已经连载33篇啦,这是一个讲人话面试系列 [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 &am ...
- JVM工作原理和特点(一些二逼的逼神面试官会问的问题)
作为一种阅读的方式了解下jvm的工作原理 ps:(一些二逼的逼神面试官会问的问题) JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完毕,通过以下4步来完毕JVM环境. ...
- Java 面试知识点解析(三)——JVM篇
前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...
- 面试官:你说你熟悉jvm?那你讲一下并发的可达性分析
这是why技术的第35篇原创文章 上面这张图是我还是北漂的时候,在鼓楼附近的胡同里面拍的. 那天刚刚下完雨,路过这个地方的时候,一瞬间就被这五颜六色的门板和自行车给吸引了,于是拍下了这张图片.看到这张 ...
随机推荐
- Java实现 蓝桥杯VIP 算法提高 身份证排序
算法提高 身份证排序 时间限制:1.0s 内存限制:256.0MB 问题描述 安全局搜索到了一批(n个)身份证号码,希望按出生日期对它们进行从大到小排序,如果有相同日期,则按身份证号码大小进行排序.身 ...
- Java实现8枚硬币问题(减治法)
1 问题描述 在8枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是较重.可以通过一架天平来任意比较两组硬币,设计一个高效的算法来检测这枚假币. 2.1 减 ...
- java实现第四届蓝桥杯马虎的算式
马虎的算式 题目描述 小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了. 有一次,老师出的题目是:36 x 495 = ? 他却给抄成了:396 x 45 = ? 但结果却很戏剧性,他的答 ...
- REDIS主从频繁切换事件排查
目录 前言 现象 排查 结论 redis主从配置注意点 前言 目前生产配置了2台redis一主一从1.193和12.6,和3个哨兵.1.193,3.10,12.6,搭建的redis高可用环境.突然发生 ...
- Base-64字符串无效,The input is not a valid Base-64 string as it contains a non-base 64 character
base64规则: * 字符串只可能包含A-Z,a-z,0-9,+,/,=字符* 字符串长度是4的倍数* =只会出现在字符串最后,可能没有或者一个等号或者两个等号 首先,C# 做上传文件的时候,需要替 ...
- css3中的@font-face你真的了解吗
css3中的自定义字体方法@font-face @font-face属性可以让我们自定义网站字体属性,然后引用到想要应用该字体的元素上. 基本语法: @font-face { font-family: ...
- [CF696D]Legen...
题目 点这里看题目. 分析 首先对于模式串建立 AC 自动机,并且计算出每个状态\(p\)的贡献总和\(con(p)\). 考虑一个朴素的 DP : \(f(i,p)\):当前串长度为 ...
- Winner Winner【模拟、位运算】
Winner Winner 题目链接(点击) 题目描述 The FZU Code Carnival is a programming competetion hosted by the ACM-ICP ...
- 在IntelliJ IDEA中注释使用的说明
/** * @author 标明该类模块的开发作者 * @version 标明该类模块的版本 * @see 参开转向,也就是相关的主题 * @param 对方法中的某些参数进行说明 * @return ...
- GestureDetector手势检测
Android手势检测器GestureDetector,要创建一个GestureDetector需要传入一个监听器GestureDetector.OnGestureListener. 案例(实现手机相 ...