大家好!我是本公众号唯一官方指定没头屑的小便--怕屁林。

 

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。

相关阅读:

飞越面试官(二)--JUC

飞越面试官(一)--Java基础

重磅!两万字Java面试知识点汇总发布!

个人公众号,关注可第一时间获取最新文章!

 

飞越面试官(三)--JVM的更多相关文章

  1. 飞越面试官(二)--JUC

    大家好!我是本号唯一官方指定没头屑的小便--怕屁林. JUC是什么东西?我相信很多经验尚浅的小伙伴部分都会为之一懵,我也是,三个字母都会读,连在一起就不知道在说什么,其实如果把它的全称写出来,“jav ...

  2. 飞越面试官(一)--Java基础

    大家好!我是本公众号唯一官方指定没头屑的小便--怕屁林. 众所周知,现场面试(包括视频面试)多数时候是没有白板,也就是说,对于你的知识点.项目经验.过往经历和个人介绍等等,都是靠一张嘴.所以考虑到这个 ...

  3. 面试高峰期,如何应对面试官的jvm刁难,特写一篇jvm面经(第一部)

    已经进入三月份,正所谓金三银四,正是一年最好的招聘期,想必我的公号粉丝们一定有不少想要跳槽的吧,哈哈,/**偷偷告诉你们其实小编也准备跳槽*/(我要加个注释,被老板知道可就完蛋了),说到面试,想必大家 ...

  4. 面试官:JVM锁优化都优化了啥?

    从JDK1.6开始,JVM对锁进行了各种优化,目的就是为了在线程间更高效的共享数据和解决互斥同步的问题.从锁优化的话题开始,可以引申出很多考点面试题,比如锁优化的技术.各优化技术的细节.CAS实现原理 ...

  5. 【对线面试官】CountDownLatch和CyclicBarrier的区别

    <对线面试官>系列目前已经连载31篇啦,这是一个讲人话面试系列 [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 &am ...

  6. 【对线面试官】Kafka基础入门

    <对线面试官>系列目前已经连载33篇啦,这是一个讲人话面试系列 [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 &am ...

  7. JVM工作原理和特点(一些二逼的逼神面试官会问的问题)

    作为一种阅读的方式了解下jvm的工作原理 ps:(一些二逼的逼神面试官会问的问题) JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完毕,通过以下4步来完毕JVM环境. ...

  8. Java 面试知识点解析(三)——JVM篇

    前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...

  9. 面试官:你说你熟悉jvm?那你讲一下并发的可达性分析

    这是why技术的第35篇原创文章 上面这张图是我还是北漂的时候,在鼓楼附近的胡同里面拍的. 那天刚刚下完雨,路过这个地方的时候,一瞬间就被这五颜六色的门板和自行车给吸引了,于是拍下了这张图片.看到这张 ...

随机推荐

  1. java实现取球游戏

    /* 今盒子里有 n 个小球,A.B 两人轮流从盒中取球,每个人都可以看到另一个人取了多少个, 也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断. 我们约定: 每个人从盒子中取出的球的 ...

  2. OC 语言特点以及与其他语言的区别

    OC 作为一门面向对象的语言,兼容c语言的语法,又有区别于其他面向对象语言的地方: 特点: 1.使用自动释放池,通过引用计数处理对象的内存管理. 2.拥有id这种通用对象类型. 3.分类,功能强大,不 ...

  3. STM32串口打印的那些知识

    常规打印方法 在STM32的应用中,我们常常对printf进行重定向的方式来把打印信息printf到我们的串口助手.在MDK环境中,我们常常使用MicroLIB+fputc的方式实现串口打印功能,即: ...

  4. 分布式数据库PolonDB 云端发力未来数据处理需求

    企业数字化转型的不断深入,传统 IT 架构和数据库早已无法适应诸如物联网.新金融.新零售.新制造等行业对于数据高吞吐.灵活扩展等需求,企业对数据库有了更高的要求. 青云QingCloud 本次推出的 ...

  5. Python3 源码阅读-深入了解Python GIL

    今日得到: 三人行,必有我师焉,择其善者而从之,其不善者而改之. 今日看源码才理解到现在已经是2020年了,而在2010年的时候,大佬David Beazley就做了讲座讲解Python GIL的设计 ...

  6. 2020/06/05 JavaScript高级程序设计 函数表达式

    函数表达式 函数定义的两种方式: 函数声明(函数声明提升,非标准name属性可访问给函数指定的名字) 函数声明提升:执行代码前先读取函数声明 function functionName(arg0, a ...

  7. 学习ASP.NET Core(10)-全局日志与xUnit系统测试

    上一篇我们介绍了数据塑形,HATEOAS和内容协商,并在制器方法中完成了对应功能的添加:本章我们将介绍日志和测试相关的概念,并添加对应的功能 一.全局日志 在第一章介绍项目结构时,有提到.NET Co ...

  8. RabbitMQ系列之【centos6 服务开启自启脚本】

    #!/bin/sh## rabbitmq-server RabbitMQ broker## chkconfig: - 80 05# description: Enable AMQP service p ...

  9. EAT表

    0X0 EAT表 在windows系统中,"库"是为了方便其他程序调用而集中包含相关的函数的文件(dll,sys).win32 API是最具有代表性的库. EAT是一种核心机制,它 ...

  10. Nginx深入浅出

    一级标题为思维导图的链接 :) 1. Nginx简介 1.1 nginx概述 说明(C10K) 程序架构(master/worker) nginx的特性 文件并发处理(异步.事件驱动)epoll / ...