当前位置: 首页 > article >正文

JVM高频面试题

1、项目中什么情况下会内存溢出,怎么解决?

	(1)误用固定大小线程池导致内存溢出  Excutors.newFixedThreadPool内最大线程数是21亿
	  (2) 误用带缓冲线程池导致内存溢出最大线程数是21亿
	  (3)一次查询太多的数据,导致内存占用太大
	  (4)动态生成类导致内存溢出

2、类加载过程?

三个过程:
	加载:

在这里插入图片描述
链接:
在这里插入图片描述
链接又分为:验证、准备、解析

	初始化:

在这里插入图片描述
总结:所谓类加载机制就是:虚拟机把Class文件加载到内存,并对数据进行校验、转换解析和初始化,形成虚拟机可以直接使用的Java类型,即java.lang.class

补充:类.class只会触发类加载且只会加载一次,而new 类()则会触发类初始化。静态变量的赋值在初始化时完成。

3、什么是双亲委派?
在这里插入图片描述

4.对象引用分为哪几类?

	1.强引用

在这里插入图片描述
正常对象引用

		2.软引用

在这里插入图片描述
系统内存足够时不会被回收,不足时才会被回收。且若回收之后仍内存不够,则会内存溢出
3.弱引用
在这里插入图片描述
无论内存是否充足都会被回收
4.虚引用
在这里插入图片描述
主要用来跟踪对象被垃圾回收的过程,任何时候都可能被垃圾回收

5、堆(heap)和栈(stack)有什么区别?
1、内存分配方式不同:堆是动态分配内存空间的;栈是静态分配内存空间的。
2、内存空间大小不同:堆的内存空间通常比较大,可以动态扩展;而栈的内存空间通常比较小,由于静态分配,所以大小固定。
3、内存分配效率不同:堆的内存分配效率相对较低,因为需要进行垃圾回收和内存整理等操作;而栈的内存分配效率相对较高,因为只需要简单地移动指针即可。
4、存储内容不同:堆用于存储对象实例和数组等动态数据,它具有很好的灵活性;而栈用于存储方法调用的局部变量和操作数栈等数据,它具有很好的局部性和快速访问的特点。

6、什么情况下会发生栈内存溢出?

方法调用层次过深:如果方法调用层次过深,每次方法调用都会在栈中创建一个新的栈帧,如果栈空间不足,就会导致栈内存溢出。
局部变量过多:如果方法中定义了大量的局部变量,也会占用栈空间,如果栈空间不足,就会导致栈内存溢出。
递归调用:递归调用会不断地向栈中添加新的方法调用,如果递归深度过大,就会导致栈内存溢出。
参数传递过多:如果方法参数传递过多,也会占用栈空间,如果栈空间不足,就会导致栈内存溢出。
大量线程调用:如果同时有大量的线程在栈中进行方法调用,也会占用栈空间,如果栈空间不足,就会导致栈内存溢出。

7、什么是OOM?
OOM 是 OutOfMemoryError 的缩写,是指在 Java 程序运行期间,由于内存不足而导致程序出现错误的情况。OOM 错误通常分为堆内存溢出和非堆内存溢出两种情况。

8、如何判断一个对象是否存活?

	1、引用计数法:引用计数法是一种简单的垃圾回收算法,它通过统计对象的引用计数,来判断对象是否存活。每当一个对象被引用时,它的引用计数加 1,当一个对象的引用计数为 0 时,说明该对象已经不再被使用,可以被垃圾回收器回收。但是,引用计数法无法处理循环引用的情况,即两个或多个对象相互引用,导致它们的引用计数都不为 0,无法被回收。
	2、可达性分析法:可达性分析法是一种常用的垃圾回收算法,它通过从一组根对象开始,查找所有被这组根对象所引用的对象,以此来确定哪些对象是存活的。在可达性分析法中,根对象可以是程序中的静态变量、本地变量或者正在执行的线程等。当一个对象无法被根对象所引用时,说明该对象已经不再被使用,可以被垃圾回收器回收。

可达性分析法是 Java 中常用的判断对象存活的方式,它考虑了对象之间的引用关系,可以处理循环引用的情况,而引用计数法则无法处理循环引用的情况,因此在 Java 中并不采用引用计数法来判断对象是否存活。

9、有哪几种垃圾回收器?各自的优点是什么?
Serial 垃圾回收器:是一种单线程的垃圾回收器,它使用标记-清除算法来回收垃圾对象。优点是简单高效,适合小型应用场景,但是在多核处理器上的表现较差。

Parallel 垃圾回收器:是一种多线程的垃圾回收器,它使用标记-整理算法来回收垃圾对象。优点是在多核处理器上的表现比 Serial 垃圾回收器更好,适合中型应用场景。

CMS 垃圾回收器:是一种并发的垃圾回收器,它使用标记-清除算法来回收垃圾对象。优点是回收效率高,暂停时间短,适合大型应用场景。但是,CMS 垃圾回收器会产生内存碎片,可能会导致频繁的 Full GC,影响应用性能。

G1 垃圾回收器:是一种并发的垃圾回收器,它使用标记-整理算法来回收垃圾对象。优点是在大型应用场景下表现良好,可以有效避免内存碎片和频繁的 Full GC。同时,G1 垃圾回收器还支持设置可预测的暂停时间,使得应用程序的性能得到进一步优化。可以优先回收大块垃圾的区域

Serial和CMS都是标记清楚,Parallel和G1都是标记整理。G1现在用的最多。

10、什么是JVM内存结构?
JVM分为堆、虚拟机栈、本地方法栈、程序计数器、方法区

虚拟机栈里有局部变量表、操作数栈、动态链接、方法返回信息

本地方法栈:是C栈,执行本地方法

程序计数器:用于记录当前虚拟机正执行的线程指令地址

堆:所有线程共享的一块内存,虚拟机开启时就创建,可通过GC进行回收。

方法区:jdk1.8之后叫元数据区


http://www.kler.cn/a/1250.html

相关文章:

  • Js的回调函数
  • mysql message from server: “Too many connections“
  • STM32F4分别驱动SN65HVD230和TJA1050进行CAN通信
  • 备忘录记事工具 四款好用的电脑备忘录记事本分享
  • 国产信创实践(国能磐石服务器操作系统CEOS +东方通TongHttpServer)
  • python注意事项:range遍历越索引现象、列表边遍历边修改出现的问题
  • 对象的动态创建和销毁以及对象的复制,赋值
  • 深入剖析Linux——进程信号
  • SpringCloud五大核心组件
  • Python每日一练(20230318)
  • 深入理解 Go slice 扩容机制
  • Redis基础篇
  • Spring 事务(编程式事务、声明式事务@Transactional、事务隔离级别、事务传播机制)
  • Spring事务和事务传播机制
  • 插件化架构设计(2):插件化从设计到实践该考量的问题汇总
  • 菱形继承和C++相关问题
  • React 用一个简单案例体验一遍 React-dom React-router React-redux 全家桶
  • Springboot集成Swagger
  • 公司测试员用例写得乱七八糟,测试总监制定了这份《测试用例编写规范》
  • 【高阶数据结构】红黑树
  • css属性学习
  • Java基础之常见运算符
  • 77.qt qml-QianWindow-V1版本界面讲解
  • @JsonFormat与@DateTimeFormat
  • go语言如何使用new构造Map
  • 【技术方案】常见库存设计方案-各种方案对比总有一个适合你