java面试---JVM

1 篇文章 0 订阅
  1. 说一下 jvm 的主要组成部分?及其作用?
    JVM内存区域由堆,方法区,虚拟机栈,本地方法栈,程序计数器五个部分组成。
    1)堆:Java对象的存储区域,任何用new字段分配的Java对象实例和数组,都被分配在堆上,Java堆可使用-Xms -Xmx进行内存控制,值得一提的是从JDK1.7版本之后,运行时常量池从方法区移到了堆上。
    2)方法区:它用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,方法区在JDK1.7版本及以前被称为永久代,从JDK1.8永久代被移除。
    3)虚拟机栈:虚拟机栈中执行每个方法的时候,都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。
    4)本地方法栈:与虚拟机栈发挥的作用相似,相比于虚拟机栈为Java方法服务,本地方法栈为虚拟机使用的Native方法服务,执行每个本地方法的时候,都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。
    5)程序计数器:指示Java虚拟机下一条需要执行的字节码指令。

  2. 说一下 jvm 运行时数据区?
    JVM运行时数据区会划分为堆,方法区,虚拟机栈,本地方法栈,程序计数器五个部分。

  3. 说一下堆栈的区别?
    栈:存取速度比堆要快,仅次于直接位于CPU中的寄存器。但是存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈数据可以共享。
    堆:可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但但是由于要在运行时动态分配内存,存取速度较慢。

  4. 队列和栈是什么?有什么区别?
    队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。
    栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表。
    队列是先进先出
    栈是先进后出的

  5. 什么是双亲委派模型?
    双亲委派模型要求除顶层启动类加载器外其余类加载器都应该有自己的父类加载器;类加载器之间通过复用关系来复用父加载器的代码。

  6. 说一下类加载的执行过程?
    类加载分三步 加载 -> 连接 ->初始化。
    1、加载:这个很简单,程序运行之前jvm会把编译完成的.class二进制文件加载到内存,供程序使用,用到的就是类加载器classLoader ,这里也可以看出java程序的运行并不是直接依 靠底层的操作系统,而是基于jvm虚拟机。如果没有类加载器,java文件就只是磁盘中的一个普通文件。
    2、连接:连接是很重要的一步,过程比较复杂,分为三步 验证 》准备 》解析   
      验证:确保类加载的正确性。
      准备:为类的静态变量分配内存,将其初始化为默认值 。 这里注意,只是为静态变量分配内存,此时是没有对象实例的 
      解析:把类中的符号引用转化为直接引用。解释一下符号引用和直接引用。
    3、初始化:为类的静态变量赋予正确的初始值,上述的准备阶段为静态变量赋予的是虚拟机默认的初始值,此处赋予的才是程序编写者为变量分配的真正的初始值。

  7. 怎么判断对象是否可以被回收?
    1.引用计数法
    给每一个对象添加一个引用计数器,每次引用计数器就加1,当引用失效的时候就减1,当计数器的值为0的时候,就可以对该对象进行回收。
    2.可达性分析算法
    将一系列的gc roots对象作为起始点,从这些节点向下搜索,搜索走过的路径称为是引用链,当gc roots对象到一个对象没有引用链的时候,称为这个对象是不可达的,此对象是不可用的,就可以进行回收。

  8. java 中都有哪些引用类型?
    强引用、软引用、弱引用、虚引用

  9. 说一下 jvm 有哪些垃圾回收算法?
    引用计数器算法、可达性分析算法

  10. 说一下 jvm 有哪些垃圾回收器?
    Serial(年轻代)、ParNew(年轻代)、Paralle Scavenge(年轻代)、Serial Old(年老代)、Parallel Old(年老代)、CMS(Concurrent Mark Sweep年老代)、G1

  11. 详细介绍一下 CMS 垃圾回收器?
    CMS收集器是为了低延迟而生,通过尽可能的并行执行垃圾回收的几个阶段来把延迟控制到最低。CMS收集器是老年代的垃圾收集器,一般情况下会有ParNew来配合执行(默认情况下也是ParNew),ParNew也是使用并行的算法来执行年轻代的回收。
    1)年老代收集器,可以和Serial、ParNew组合使用
    2)采用 ”标记-清除“算法,可以通过设置参数在垃圾回收时进行内存碎片的整理
    3)CMS是并发算法,表示垃圾回收和用户进行同时进行,但是不是所有阶段都同时进行,在初始标记、重新标记阶段还是需要Stop the World。CMS垃圾回收分这四个阶段:初始标记、并发标记、重新标记、并发清除
    4)适合于对响应时间要求高的系统
    缺点
    1)对CPU资源非常敏感
    2)、CMS收集器无法处理浮动垃圾,即清除时用户进程同时产生的垃圾,只能等到下次GC时回收
    3)、因为是使用“标记-清除”算法,所以会产生大量碎片

  12. 新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?
    Serial(年轻代)、ParNew(年轻代)、Paralle Scavenge(年轻代)、Serial Old(年老代)、Parallel Old(年老代)、CMS(Concurrent Mark Sweep年老代)、G1
    新生代可用的gc方式有:串行gc(Serial Copying),并行回收gc(Parellel Scavenge),并行gc(ParNew).
    旧生代和年老代可用的gc方式有串行gc(Serial MSC),并行gc(Parallel MSC),并发gc(CMS)。

  13. 简述分代垃圾回收器是怎么工作的?
    1、引用计数机制:
    这是一种简单但速度很慢的垃圾回收技术,每个对象都含有一个计数器,当引用连接至对象时,计数器 +1;当引用离开作用域或被置为null时,计数器 -1(就是对象被引用一次,计数器 +1,引用被撤销一次,计数器 -1);虽然管理引用计数的开销不大,但是这项开销在整个程序生命周期中将持续发生。垃圾回收器会在会在含有全部对象的列表进行便利,当发现某个对象的引用计数为0时,就释放其占有的空间(但是,引用计数模式经常会在计数值变为0时立即释放对象)。
    注:这种方法有个缺陷,如果对象之间存在循环引用,可能会出现“对象应该被回收,但是引用计数不为0”的情况。
    对于垃圾回收器而言,定位这样的交互自引用的对象组所需的工作量极大,所以一般这种方式只用来说明垃圾收集的工作方式,并未被应用于虚拟机中。
    2、设计思路——追溯引用
    自适应的垃圾回收机制的设计思路是追溯引用;垃圾回收器依据的思想是:任何“活”的对象,最终一定能追溯到其存活在堆栈或静态存储区之中的引用。这个引用链条可能会穿越整个对象层次。反之,从堆栈或静态存储区出发,遍历所有的引用,就能找到所有获得对象。对于发现的每个引用,追踪到它所引用的对象,然后再对对象的所有引用执行这种操作。直到“根源于堆栈或静态存储区的引用”所形成的网络全部被访问为止,这样所有访问过得对象都是“活”的,没有被访问过得就自定被回收了。
    注:这就解决了“交互自引用的对象组”问题。
    3、自适应(复制-停止(stop-and-copy))回收机制
    这种机制具体为,先暂停程序的运行(所以他不属于后台回收模式),然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全是垃圾。这种方式可以使对象在堆中保持紧凑排列。
    缺点:这种“复制式回收器”效率会降低,有两个原因,
    首先,要有两个堆,然后在这两个堆之间倒腾,从而得维护比实际需要的多一倍的时间。
    在java虚拟机对此问题的处理方式是,分配几块较大的内存,复制动作发生在这些大的内存块之间。
    第二,程序进入稳定之后,可能只会产生少量垃圾,甚至没有垃圾,但是复制式回收器依然会工作,造成浪费。
    4、自适应(标记-清扫(mark-and-sweep))回收机制
    这种体制同样也要先暂停程序才能进行,它的思想同样追随引用,从堆栈或静态存储区出发,遍历所有的引用,进而找出所有存活对象,找到一个存活对象就标记一个。这个过程不会发生回收任何对象,而是全部标记工作完成后,才会清理未被标记的对象。这个过程不会发生任何复制动作,所以剩下的堆空间是不连续的,垃圾回收器如果希望得到连续空间的话,要重新整理剩下的对象。
    5、“块”机制
    在有了“块”之后,垃圾回收器在回收的时候就可以往废弃的“块”里拷贝对象了,每个块都有相应的 “代数”来记录他是否还存活;具体为,“块”在某处被引用,其代数就会增加,垃圾回收器会对上次回收之后新分配的“块”进行整理。这对“短命”的临时对象很有帮助。

  14. 说一下 jvm 调优的工具?
    jdk自带的工具jconsole、VisualVM
    第三方调优工具MAT、GChisto、gcviewer

  15. 常用的 jvm 调优的参数都有哪些?
    -Xmx:最大JVM可用内存, 例:-Xmx4g
    -Xms:最小JVM可用内存, 例:Xms4g
    -Xmn:年轻代内存大小,例:-Xmn2560m
    -XX:PermSize:永久代内存大小,该值太大会导致fullGC时间过长,太小将增加fullGC频率,例:-XX:PermSize=128m
    -Xss:线程栈大小,太大将导致JVM可建的线程数量减少,例:-Xss256k
    -XX:+DisableExplicitGC:禁止手动fullGC,如果配置,则System.gc()将无效,比如在为DirectByteBuffer分配空间过程中发现直接内存不足时会显式调用System.gc()
    -XX:+UseConcMarkSweepGC:一般PermGen是不会被GC,如果希望PermGen永久代也能被GC,则需要配置该参数
    -XX:+CMSParallelRemarkEnabled:GC进行时标记可回收对象时可以并行remark-XX:+UseCMSCompactAtFullCollection 表示在fullGC之后进行压缩,CMS默认不压缩空间
    -XX:LargePageSizeInBytes:为java堆内存设置内存页大小,例:-XX:LargePageSizeInBytes=128m
    -XX:+UseFastAccessorMethods:对原始类型进行快速优化
    -XX:+UseCMSInitiatingOccupancyOnly:关闭预期开始的晋升率的统计
    -XX:CMSInitiatingOccupancyFraction:使用cms作为垃圾回收,并设置GC百分比,例:-XX:CMSInitiatingOccupancyFraction=70(使用70%后开始CMS收集)
    -XX:+PrintGCDetails:打印GC的详细信息
    -XX:+PrintGCDateStamps:打印GC的时间戳
    -Xloggc:指定GC文件路径

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值