jvm面试题目补充

news/2024/12/14 17:42:03/

jdk&jre

Java程序设计语言、Java虚拟机、Java API类库这三部分统称为JDK(Java Development Kit)。

把Java API类库中的Java SE API子集 [1] 和Java虚拟机这两部分统称为JRE(Java Runtime Environment),JRE是支持Java程序运行的标准环境

HotSpot VM:

HotSpot指的就是它的热点代码探测技术

垃圾回收中的空间分配担保

为了减少垃圾回收时间

minor gc前,检查老年代最大连续可用空间是否大于新生代对象总大小,如大于,则进行minor gc;

如小于,检查是否开启了分配担保,未开启,直接full gc;

开启后,检查老年代最大连续可用空间是否大于历次晋升老年代对象大小,小于则进行minorgc,同时将新生代放不下的对象提前放到老年代中,大于则full gc

根节点枚举

在特定位置时就记录对象关系到OopMap中

暂停用户线程;使用OopMap存储:类加载完成时,将什么对象存储在什么位置取出来;即时编译时,将对象存储取出放到特定位置;不需要一字不漏的将gcroot从方法区等位置取出

安全点

在特定的位置生成OopMap记录,称为安全点;到安全点时,用户线程才停止,进行垃圾回收

用户线程主动式中断:主动轮询中断标识,为true时,中断

  • 循环的末尾
  • 方法返回前
  • 调用方法的 call 之后
  • 抛出异常的位置

安全区

用户线程sleep或者blocked状态时,无法响应系统的中断请求,挂起自己线程

某个区域内,引用关系不会发生变化,进行垃圾回收是安全的

记忆集和卡表

存在跨区域垃圾回收时,GC root并不是包含所有区域的root节点,非回收区域存在回收区域的指针时,才需要加入gc root节点;用于缩小gc root扫描范围

使用以下结构存储了这些引用关系

记忆集:是否存在非回收区域指向回收区域的指针

卡表是记忆集(一种抽象概念)的实现,一个卡表存在多个卡页,一个卡页存在一个(或多个对象)对象存在跨代指针时,记录变脏标志为1,后续将这个内存页的数据加入GC ROOT一并扫描

写屏障

卡表变脏时间:引用类型对象赋值时,卡表可能变脏

引用类型对象赋值后,使用写后屏障,更新卡表。

写前屏障在G1垃圾处理器后才使用到

三色标记:并发标记阶段(可达性分析)

gcroot向下遍历对象时的算法

按照是否被垃圾回收器访问过,分为白色(没被访问过,不可达),黑色(被访问过,所有引用都被访问过,不能直接指向白色,需通过灰色间接指向白色,原因是黑色是被遍历完成的,下次标记不能重新扫描引用,此时白色会被误清理),灰色(至少一个引用未被访问过,正在枚举过程中)

假设访问对象A,访问对象A的所有引用,变为灰色对象,访问完成时,将A变为黑色对象;所有对象遍历完成时,剩余的白色对象即为垃圾;

并发标记阶段,用户线程同步进行,对象的引用关系发生了变化,因此在重新标记阶段需要对变化的引用进行处理;

引用关系两种变化场景:

1 删除引用,黑色对象引用被删除,成为浮动垃圾,下次垃圾回收时回收即可;

2 新增引用,黑色对象下添加白色对象A->F,当原来引用白色的关系被删除时B.f=null,此时进行重新标记时,B变为黑色,F还是白色,会被误清理

解决方案

增量更新

从增量角度,A.f=F,增加引用时,添加写屏障,将黑色引用白色的引用关系记录一下,重新标记时,将引用关系重新扫描,实现方案是将A变为灰色,a的引用关系重新扫描

原始快照

从删除角度,在执行B.f=nul,插入一个写屏障,记录B.f,再进行置空操作,重新标记时,将B.F变为黑色对象,不管吧B.F是否还有引用都不会被清理,如果没有引用下次垃圾回收会清理掉。宁可放过,不可杀错的思想。

引用逃逸

如果一个对象的指针被多个方法或者线程引用时,那么我们就称这个对象的指针发生了逃逸。

gcroot包含静态类,synch锁定对象、常量池中对象

垃圾回收

fullgc场景

大对象(sql未分页等)分配

metaspace溢出,classloader未回收导致元空间溢出,发生full gc

内存泄漏,由于内存泄漏会导致内存溢出

jvm参数设置不合理

内存溢出

不断创建对象时,gc root存在引用关系时,堆空间不足时会发生内存溢出

确认oom对象是否是必要的,即内存泄漏还是内存溢出,内存泄漏需要使用工具判断引用链,内存溢出需要判断堆大小相关配置

StackOverflow

虚拟机容量太小,栈帧太大,都会引起新的栈帧无法分配内存

线程请求栈的深度大于虚拟机允许的最大深度时

oom

创建线程时无法获得内存时会出现oom(jvm实现上不允许栈自动扩容,理论上允许)

方法区(类型信息(类名,父类,修饰符,实现的接口列表等)、域(属性)、方法、常量、静态变量,运行时的常量池,编译后的代码缓存)

垃圾回收主要包含:常量池和类的卸载

jdk1.6 PerGen OOM

jdk1.7 java heap

jdk1.8 metasapce oom

本地直接内存

使用NIO时,日志内容较少

永久代和方法区的关系?和元空间的关系?

收集器的分代设计扩展到方法区时,用永久代的概念实现方法区的垃圾回收,效果不理想,因此从jdk7开始逐步将永久代的字符串常量池和静态变量等移出(堆中),jdk8中永久代消失,将剩余内容(主要是类型信息)移动到直接内存metaspace元空间中

gc和内存溢出的关系

分配空间时,发现空间不足(应用空闲时也会)时会进行gc,gc后空间还不够,抛出内存溢出相关异常

减少GC开销的措施 

 (1)不要显式调用System.gc()  此函数建议JVM进行主GC,虽然只是建议而非一定,但很多情况下它会触发主GC,从而增加主GC的频率,也即增加了间歇性停顿的次数。 

 (2)尽量减少临时对象的使用  临时对象在跳出函数调用后,会成为垃圾,少用临时变量就相当于减少了垃圾的产生,从而延长了出现上述第二个触发条件出现的时间,减少了主GC的机会。 

 (3)对象不用时最好显式置为Null  一般而言,为Null的对象都会被作为垃圾处理,所以将不用的对象显式地设为Null,有利于GC收集器判定垃圾,从而提高了GC的效率。 

 (4)尽量使用StringBuffer,而不用String来累加字符串  由于String是固定长的字符串对象,累加String对象时,并非在一个String对象中扩增,而是重新创建新的String对象,如Str5=Str1+Str2+Str3+Str4,这条语句执行过程中会产生多个垃圾对象,因为对次作“+”操作时都必须创建新的String对象,但这些过渡对象对系统来说是没有实际意义的,只会增加更多的垃圾。避免这种情况可以改用StringBuffer来累加字符串,因StringBuffer是可变长的,它在原有基础上进行扩增,不会产生中间对象。 

 (5)能用基本类型如Int,Long,就不用Integer,Long对象  基本类型变量占用的内存资源比相应对象占用的少得多,如果没有必要,最好使用基本变量。 

 (6)尽量少用静态对象变量  静态变量属于全局变量,不会被GC回收,它们会一直占用内存。

 (7)分散对象创建或删除的时间  集中在短时间内大量创建新对象,特别是大对象,会导致突然需要大量内存,JVM在面临这种情况时,只能进行主GC,以回收内存或整合内存碎片,从而增加主GC的频率。集中删除对象,道理也是一样的。它使得突然出现了大量的垃圾对象,空闲空间必然减少,从而大大增加了下一次创建新对象时强制主GC的机会。


http://www.ppmy.cn/news/1364685.html

相关文章

MySQL数据库运维第一篇(日志与主从复制)

文章目录 一、错误日志二、二进制日志三、查询日志四、慢查询日志(记录超时的sql语句)五、主从复制概括六、主从复制原理七、搭建主从复制八、主从复制的测试 在这篇深入的技术文章中,作者将以明晰透彻的方式详细介绍MySQL数据库中关键的日志…

【论文阅读】基于人工智能目标检测与跟踪技术的过冷流沸腾气泡特征提取

Bubble feature extraction in subcooled flow boiling using AI-based object detection and tracking techniques 基于人工智能目标检测与跟踪技术的过冷流沸腾气泡特征提取 期刊信息:International Journal of Heat and Mass Transfer 2024 级别:EI检…

在Pycharm中运行Django项目如何指定运行的端口

方法步骤: 打开 PyCharm,选择你的 Django 项目。在菜单栏中,选择 “Run” -> “Edit Configurations...”。在打开的 “Run/Debug Configurations” 对话框中,选择你的 Django server 配置(如果没有,你…

python中map函数

map(str, path): map函数会将path中的每一个元素传递给str函数,从而将它们转换为字符串。 如果path是一个数字列表,例如[1, 2, 3],那么map(str, path)将返回[1, 2, 3]。 在写二叉树时用到map给树节点进行str转换是错的。 map(s…

MySQL集群 双主架构(配置命令)

CSDN 成就一亿技术人&#xff01; 今天刚开学第一天给大家分享一期&#xff1a;MySQL集群双主的配置需求和命令 CSDN 成就一亿技术人&#xff01; 神秘泣男子主页&#xff1a;作者首页 <———— MySQL专栏 &#xff1a;MySQL数据库专栏<———— MySQL双主是一…

使二叉树所有路径值相等的最小代价

1.题目 这道题使2024-2-28的签到题&#xff0c;题目难度为中等。 考察知识点&#xff1a;贪心 满二叉树 题目链接&#xff1a;2673. 使二叉树所有路径值相等的最小代价 - 力扣&#xff08;LeetCode&#xff09; 2.思路 在做这道题之前我们得知道满二叉树是什么&#xff1f…

解决Docker镜像中CentOS 8仓库问题

前言&#xff1a; 在yum执行过程中&#xff0c;持续遇到与CentOS 8上的’appstream’仓库元数据检索相关的错误。具体错误消息为&#xff1a;“错误&#xff1a;下载’appstream’仓库元数据失败&#xff1a;无法准备内部镜像列表&#xff1a;镜像列表中没有URL。” 问题分析&…

【漏洞复现】鸿运(通天星CMSV6车载)主动安全监控云平台存在敏感信息泄露漏

漏洞描述 鸿运(通天星CMSV6车载)主动安全监控云平台实现对计算资源、存储资源、网络资源、云应用服务进行7*24小时全时区、多地域、全方位、立体式、智能化的IT运维监控,保障IT系统安全、稳定、可靠运行。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法…