文档章节

Java虚拟机常见面试题

 细节探索者
发布于 02/12 00:21
字数 2224
阅读 18
收藏 0

1、java引用的四种状态

强引用、软引用、弱引用、虚引用。

强引用

new一个Object存放在堆内存,然后用一个引用指向它,这个就是强引用。

如果一个对象具有强引用,那垃圾回收器不会回收它。当内存空间不足,java虚拟机宁愿抛出outOfMemoryError错误,使程序异常终止,也不会随意回收具有强引用的对象来解决内存不足的问题。

软引用

如果一个对象只具有软引用,则内存空间足够时,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。

只要垃圾回收器没有回收它,该对象就可以被程序使用。弱引用可用来实现内存敏感的高速缓存。

弱引用

只具有弱引用的对象拥有更短暂的生命周期。

每次执行GC的时候,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

虚引用

"虚引用",形同虚设,与其他几种引用不同,虚引用并不会决定对象的生命周期,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

虚引用主要用来跟踪对象被垃圾回收器的活动。

2、java中的内存划分

2.1 程序计数器

内存空间小,线程私有。字节码解释器工作是就是通过改变这个计数器的值来选取下一条需要执行指令的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖计数器完成

如果线程正在执行一个 Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是 Native 方法,这个计数器的值则为 (Undefined)。此内存区域是唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域。

2.2 虚拟机栈

线程私有,生命周期和线程一致。描述的是 Java 方法执行的内存模型:每个方法在执行时都会床创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程。

局部变量表:存放了编译期可知的各种基本类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型)和 returnAddress 类型(指向了一条字节码指令的地址)

StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。 OutOfMemoryError:如果虚拟机栈可以动态扩展,而扩展时无法申请到足够的内存。

2.3 本地方法栈

区别于 Java 虚拟机栈的是,Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。也会有 StackOverflowError 和 OutOfMemoryError 异常。

2.4 堆

对于绝大多数应用来说,这块区域是 JVM 所管理的内存中最大的一块。线程共享,主要是存放对象实例和数组。内部会划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer, TLAB)。可以位于物理上不连续的空间,但是逻辑上要连续。

OutOfMemoryError:如果堆中没有内存完成实例分配,并且堆也无法再扩展时,抛出该异常。

2.5 方法区

属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

2.6 运行时常量池

属于方法区的一部分。

属于方法区一部分,用于存放编译期生成的各种字面量和符号引用。编译器和运行期(String 的 intern() )都可以将常量放入池中。内存有限,无法申请时抛出 OutOfMemoryError。

2.7 直接内存

非虚拟机运行时数据区的部分

在 JDK 1.4 中新加入 NIO (New Input/Output) 类,引入了一种基于通道(Channel)和缓存(Buffer)的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。可以避免在 Java 堆和 Native 堆中来回的数据耗时操作。 OutOfMemoryError:会受到本机内存限制,如果内存区域总和大于物理内存限制从而导致动态扩展时出现该异常。

3、java对象在内存中的状态

3.1 可达的/可触及的

从根节点扫描,只要这个对象在引用链,就是可达的。

3.2 可恢复的

java对象不再被任何变量引用就进入了可恢复状态。

在回收该对象之前,该对象的finalize()方法进行资源清理。如果在finalize()方法中重新让变量引用该对象,则对象再次变为可达状态,否则改状态进入不可达状态。

3.3 不可达的

java对象不被任何变量引用,且系统在调用对象finalize()方法后,依然没有使该对象变成可达状态,则该对象变成不可达状态。

当java对象处于不可达状态时,系统才会真正回收该对象所占有的资源。

4.判断对象死亡的两种常用算法

4.1 引用计数算法

4.2 根搜索算法

5.垃圾回收算法

5.1 标记-清除算法

算法分为标记和清除两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

不足:一个是效率问题,标记和清除两个过程的效率都不高,另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后再程序运行过程中需要分配较大的对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。 清除不是擦除,内容不会被马上清空,直到有新的的内容写入才会覆盖。

5.2 复制算法

它将可用内存按照容量划分为大小相等的两块,每次只使用其中的一块。当这块的内存用完了,就将还活着的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可。

不足:内存浪费。

实际中我们并不需要按照1:1比例来划分内存空间,如堆内存的新生代,将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor,当另一个Survivor空间没有足够空间存放上一次新生代收集下来的存活对象时,这些对象将直接通过分配担保机制进入老年代。

5.3 标记-整理算法

让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。 主要用在老年代中

5.4 分代收集算法

存活率低:青年代采用复制算法。 存活率高:标记清理/标记整理算法

6.垃圾收集器

6.1 Serial收集器

6.2 ParNew 收集器

6.3 ParNew Scanvenge 收集器

6.4 CMS收集器

6.5 G1 收集器

7.java堆内存划分

7.1 青年代

7.2 老年代

8.类加载机制

9.初始化顺序

10.JVM参数

10.1 java对象分配与vm调优

引用

JVM常见面试题1

jvm常见面试题2

3

https://blog.csdn.net/qq_41701956/article/details/81664921

© 著作权归作者所有

共有 人打赏支持
粉丝 24
博文 271
码字总数 347783
作品 0
杭州
程序员
私信 提问
面试中关于Java虚拟机(jvm)的问题看这篇就够了

最近看书的过程中整理了一些面试题,面试题以及答案都在我的文章中有所提到,希望你能在以问题为导向的过程中掌握虚拟机的核心知识。面试毕竟是面试,核心知识我们还是要掌握的,加油~~~ 下面...

snailclimb
2018/05/12
0
0
阿里巴巴菜鸟Java一面11个问题,你会几个呢?

近日,w3cschool app开发者头条上分享了阿里菜鸟Java程序员一些面试题。 这吸引了不少程序员小伙伴们的注意。 在分享阿里菜鸟Java程序员面经前,来看下Java面试一些面试经验分享: 0、Java高...

W3Cschool
2018/04/03
0
0
金九银十,史上最强 Java 面试题整理。

以下会重新整理所有 Java 系列面试题答案、及各大互联网公司的面试经验,会从以下几个方面汇总,本文会长期更新。 Java 面试篇 史上最全 Java 面试题,带全部答案 史上最全 69 道 Spring 面试...

Java技术栈
2018/09/13
0
0
Java面试:投行的15个多线程和并发面试题

本文由ImportNew -一杯哈希不加盐 翻译自dzone。欢迎加入翻译小组。转载请见文末要求。 多线程和并发问题已成为各种 Java 面试中必不可少的一部分。如果你准备参加投行的 Java 开发岗位面试,...

ImportNew
2018/08/23
0
0
BAT等大厂Android面试书单和知识点清单

java是Android开发的基础,在BAT的初面中,会涉及到比较多的java基础知识,所以比较重要,下面我介绍的书籍内容是由浅到深。 1.Thinking in java:这本书被称为Java的三大圣经之一,虽然书比...

android自学
2018/07/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Httpd 整合 Tomcat 步骤

环境:Tomcat8 + Httpd2.4 工作原理:借助于Tomcat的AJP连接器实现Apache与Tomcat的通信 配置步骤: 1. 配置httpd.conf 新增: Include conf/extra/mod_jk.conf 修改:添加 index.jsp <IfM...

ZeroneLove
昨天
1
0
Docker笔记3——容器命令(未写完,明天整理接着写)

未写完,明天整理接着写 新建并启动容器 docker run docker run [OPTIONS] IMAGE [COMMEND] [ARG...] OPTIONS: --name=[容器新名字] :为容器指定一个名称 -d:后台运行容器,并返回容器ID,...

HappyBKs
昨天
1
0
2018个人年终总结

感谢领导的信任和指导,新的一年获得了很多成长和提高,改掉了很多不好的习惯。 在这一年里,我在领导的帮助下,主要完成了以下功能: 1、完成上海银行版本投资营销相关功能的开发。 2、完成车...

万山红遍
昨天
12
0
保密工作与linux系统的发展

保密工作从性质上可以分成商业方面的保密和国家安全方面的保密。由于自己从事的是IT方面的工作,工作中必然会接触涉及到计算机信息方面的相关文件。加上单位已近通过武器装备科研生产单位二级...

linux-tao
昨天
3
0
Spark共享变量

概述 Spark程序的大部分操作都是RDD操作,通过传入函数给RDD操作函数来计算。这些函数在不同的节点上并发执行,但每个内部的变量有不同的作用域,不能相互访问,所以有时会不太方便,Spark提...

仟昭
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部