JVM面试题(二)

news/2024/6/16 10:13:30/文章来源:https://blog.csdn.net/jianing1018/article/details/137196123

###1. 对象的访问定位的两种方式?
Java对象的访问定位主要有两种方式:句柄访问和直接指针访问。

  1. 句柄访问

在句柄访问方式中,Java堆会被划分为两部分:一部分存放对象实例数据,另一部分存放对象实例数据的地址。引用实际上是指向句柄的引用,而不是直接指向对象。句柄作为一个间接指针,包含了对象实例数据与类型数据各自具体的地址信息。由于句柄是间接访问,它使得Java堆可以实现固定大小,对象实例数据可以被移动和重分配。然而,这种方式增加了一次间接访问的开销,从而可能降低程序的执行效率。
2. 直接指针访问

在直接指针访问方式中,对象实例数据直接存放在Java堆中,对象引用直接指向对象实例数据的地址。这种方式减少了间接访问的开销,因此提高了程序的执行效率。目前,大多数Java虚拟机采用直接指针方式作为对象的访问定位方式,因为随着硬件的发展和虚拟机技术的进步,间接访问的开销已经可以被忽略不计。

这两种方式的选择主要由虚拟机的实现决定,而在实际的JVM中,可以根据具体的应用场景和性能需求来选择合适的访问定位方式。

###2. 判断垃圾可以回收的方法有哪些?
在Java中,垃圾回收(Garbage Collection, GC)是由Java虚拟机(JVM)自动管理的内存回收机制。Java程序员通常不需要(也不应该)直接判断或控制哪些对象应该被回收。JVM的垃圾回收器会根据对象的可达性来决定哪些对象可以被回收。

但是,如果你想要了解Java中对象何时可能变得不可达,或者何时可能被垃圾回收器标记为可回收的,你可以考虑以下几个方面:

  1. 引用计数法:这是一种早期的垃圾回收策略,但它并没有被Java采用。在这种方法中,每个对象都有一个引用计数器,每当有一个地方引用该对象时,计数器就加1;引用释放时,计数器就减1。当计数器为0时,对象就被认为是垃圾。但是,这种方法不能处理循环引用的情况。

  2. 可达性分析算法:这是Java采用的主要垃圾回收判断方法。从一组根对象(通常是静态变量、常量引用、活跃线程栈中的引用等)开始,递归地搜索这些对象可达的所有对象。搜索路径上遇到的所有对象都被认为是可达的,也就是“存活”的。搜索结束后,未被访问到的对象就是不可达的,即“垃圾”对象,可以被回收。

  3. finalize()方法:Java提供了一个finalize()方法,当垃圾回收器确定不存在对该对象的更多引用时,对象的finalize()方法会被调用。但请注意,finalize()方法并不是用来控制垃圾回收的,而是提供了一种在对象被回收前执行清理操作的机制。而且,依赖finalize()方法进行垃圾回收是不推荐的,因为垃圾回收的时机是不确定的,且finalize()的执行也可能被JVM优化掉。

  4. 弱引用、软引用和虚引用:Java还提供了几种不同的引用类型,用于更精细地控制对象的生命周期和垃圾回收。这些引用类型包括:

    • 弱引用(WeakReference):弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收只被弱引用关联的对象。
    • 软引用(SoftReference):软引用是用来描述一些可能还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。
    • 虚引用(PhantomReference):虚引用是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

总的来说,虽然Java程序员不能直接控制垃圾回收的过程,但可以通过理解对象的引用类型和生命周期,以及避免内存泄漏等方式,来更有效地管理内存使用。

###3. 垃圾回收是从哪里开始的呢?
Java垃圾回收从根对象开始。这些根对象包括静态变量、活动线程、本地方法栈中JNI(Java Native Interface)引用的对象等。垃圾回收器会从这些根对象出发,通过引用关系遍历整个对象图,找出所有可达对象。那些无法通过根对象追踪到的对象,就被认为是垃圾对象,进而被垃圾回收器标记并清理。因此,Java垃圾回收的起点是这些根对象。

需要注意的是,Java的垃圾回收过程并不是实时的,也就是说,一个对象成为垃圾后,并不会立即被回收。具体的回收时机取决于JVM的垃圾回收策略和垃圾回收器的类型。此外,为了配合垃圾回收,堆内存会被划分为不同的区域,如新生代和老年代,每个区域都有其特定的垃圾回收策略和处理方式。

总的来说,Java垃圾回收从根对象开始,通过遍历对象图来找出并清理垃圾对象,这是Java内存管理的重要部分,有助于确保程序的稳定运行和内存的有效利用。

###4. 被标记为垃圾的对象一定会被回收吗?
在Java中,即使一个对象被标记为垃圾(即不可达),也并不意味着它一定会立即被回收。对象的回收时机是由Java的垃圾回收器(Garbage Collector, GC)来决定的,而垃圾回收器的工作是受到JVM的垃圾回收策略、堆内存的使用情况、系统负载等多种因素影响的。

具体来说,当对象被判定为不可达时,它首先会被标记为可回收对象。然而,这并不意味着对象会立即被清理掉。JVM的垃圾回收器会定期进行垃圾回收操作,在这个过程中,它会检查所有被标记为可回收的对象,并尝试释放这些对象占用的内存。

此外,Java的垃圾回收机制还包含了一些优化策略,例如分代收集(Generational Collection)。在这种策略下,不同“年龄”的对象会被分配到不同的内存区域,并且垃圾回收的频率和方式也会有所不同。这有助于提高垃圾回收的效率,减少不必要的内存开销。

需要注意的是,虽然Java的垃圾回收机制可以自动管理内存,但程序员仍然需要注意避免内存泄漏等问题。例如,避免创建长生命周期的对象引用短生命周期的对象,或者避免在静态变量中持有不必要的对象引用等。

因此,被标记为垃圾的对象不一定会立即被回收,而是会在垃圾回收器进行垃圾回收操作时根据一定的策略进行清理。

###5. 谈谈对 Java 中引用的了解?
在Java中,引用是Java内存管理中的一个核心概念,它是对象在内存中的地址的抽象表示。Java中的引用主要有以下几种类型:

  1. 强引用(Strong Reference):这是最常见的引用类型。一个对象只要有一个强引用指向它,它就不会被垃圾回收器回收。即使内存空间不足,JVM宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的“存活”对象来解决内存不足问题。
  2. 软引用(Soft Reference):软引用是用来描述一些可能还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。
  3. 弱引用(Weak Reference):弱引用也是用来描述非必需对象的,它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
  4. 虚引用(Phantom Reference):虚引用是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

引用类型在Java内存管理和垃圾回收中起着重要作用。它们决定了对象在内存中的生命周期,以及垃圾回收器如何处理这些对象。正确理解和使用引用类型,可以帮助我们更有效地管理Java程序的内存,避免内存泄漏和内存溢出等问题。

此外,Java 9还引入了新的引用类型——清理器引用(Cleaner Reference),它用于替代PhantomReference和ReferenceQueue,提供了一种更加灵活和强大的方式来管理对象在内存中的生命周期。清理器引用可以与一个或多个清除动作关联,当对象被垃圾回收器回收时,这些清除动作会被自动执行。这提供了一种更直观和简洁的方式来处理对象被回收时的清理工作。

###6. 谈谈对内存泄漏的理解?
内存泄漏(Memory Leak)是计算机科学中的一个重要概念,尤其在处理如Java这样的编程语言时显得尤为关键。当程序中已动态分配的堆内存由于某种原因未被释放或无法释放时,就会发生内存泄漏。这会导致系统内存的浪费,可能引发程序运行速度减慢,甚至可能导致系统崩溃等严重后果。

内存泄漏的原因有很多,包括但不限于:

  1. 数据量过于庞大,导致程序在运行过程中占用了大量的内存,而这部分内存在使用完毕后没有得到及时释放。
  2. 程序中存在死循环,导致某些对象或资源无法被正常回收。
  3. 静态变量和静态方法使用过多,由于静态变量的生命周期与程序的生命周期相同,如果大量使用静态变量,可能会导致内存占用过高且无法释放。
  4. 递归调用时没有正确处理内存释放,也可能导致内存泄漏。
  5. 存在无法确定是否被引用的对象,这些对象可能长时间占用内存而无法被垃圾回收器回收。

此外,虚拟机不回收内存也是内存泄漏的一个原因。当程序运行所需的内存大于虚拟机能提供的最大内存时,就会发生内存溢出。虽然内存溢出的问题在不同系统和业务中有所不同,但优化程序代码,减少全局变量的引用,以及让程序在使用完变量后及时释放该引用,都是有效的解决方法。

内存泄漏的危害主要体现在两个方面:一是频繁触发垃圾回收(GC),导致应用卡顿,影响用户体验;二是当内存不足以分配某些需要的内存时,会导致应用崩溃。

为了解决内存泄漏问题,可以采取以下策略:

  1. 使用垃圾回收器跟踪对象和变量引用的情况,并释放它们所占用的内存。
  2. 确保在资源使用完毕后及时关闭,如数据库连接、文件流、网络连接等。
  3. 避免在代码中出现循环引用的情况,以减少对象长时间存在而无法被回收的可能性。
  4. 使用合适的数据类型来管理对象和数据,以提高内存使用效率。
  5. 使用工具来检测内存泄漏,以便及时发现并解决问题。

总的来说,理解内存泄漏的原理和危害,以及掌握有效的预防和解决策略,对于确保程序的稳定运行和提供良好的用户体验至关重要。

###7. 内存泄露的根本原因是什么?
内存泄漏的根本原因在于程序中已动态分配的堆内存由于某种原因未被释放或无法释放,导致系统内存浪费。具体来说,内存泄漏的原因可能包括:

  1. 忘记释放内存:程序员在编写代码时可能会忘记释放已经申请的内存空间,导致这部分内存无法被再次利用。
  2. 异常处理不当:当程序发生异常时,如果没有正确处理异常,就会导致程序无法正常释放已经申请的内存空间,从而引起内存泄漏。
  3. 循环引用:当两个或多个对象之间存在循环引用时,它们都无法被释放,从而引起内存泄漏。
  4. 资源未关闭:在使用一些资源(如数据库连接、文件句柄等)时,如果没有正确关闭这些资源,它们占用的内存就无法被释放,从而引起内存泄漏。

此外,长生命周期的对象持有短生命周期对象的引用也可能导致内存泄漏。由于长生命周期对象持续存在,它持有的对短生命周期对象的引用使得垃圾回收器(GC)无法回收这些短生命周期对象,即使它们已经不再使用,从而造成内存空间的浪费。

内存泄漏会减少可用内存的数量,降低计算机的性能,甚至可能导致系统崩溃等严重后果。因此,程序员应该养成及时释放不再使用的内存的好习惯,正确处理异常,避免循环引用,以及正确关闭资源,以预防内存泄漏的发生。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1034526.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenHarmony实战:轻量带屏解决方案之恒玄芯片移植案例

本文章基于恒玄科技 BES2600W 芯片的欧智通 Multi-modal V200Z-R 开发板,进行轻量带屏开发板的标准移植,开发了智能开关面板样例,同时实现了 ace_engine_lite、arkui_ui_lite、aafwk_lite、appexecfwk_lite、HDF 等部件基于 OpenHarmony Lite…

Python 与机器学习,在服务器使用过程中,常用的 Linux 命令包括哪些?

🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 本博客旨在分享在实际开发过程中,开发者需要了解并熟练运用的 Linux 操作系统常用命令。Linux 作为一种操作系统,与 Windows 或 MacOS 并驾齐驱,尤其在服务器和开发环…

阿里云向量检索服务 | 全性能搜索方案

阿里云向量检索服务 | 全性能搜索方案 什么是向量检索服务拍照搜商品AI问答 基于向量检索服务与TextEmbedding实现语义搜索什么是Embedding开通灵积模型服务开通向量检索服务安装Python安装环境准备数据安装Git 通过 DashScope 生成 Embedding 向量通过 DashVector 构建检索&am…

c语言中的柔性数组

目录 1.柔性数组的特点 2.柔性数组的创建和简单使用 3.柔性数组的优势 何为柔性数组(Flexible Array) 柔性数组在C语言的 C99 标准中,引入的新特性。结构中的最后一个元素的大小允许是未知的数组,即为柔性数组。 struct S {in…

m2ts是什么文件格式?m2ts手机能播放吗?

大多数现代手机可以播放M2TS(MPEG-2 Transport Stream)格式的视频文件,但也取决于手机型号和操作系统。某些手机可能需要安装第三方播放器才能播放此格式的视频。如果您的手机无法直接播放M2TS文件,可以尝试使用视频转换工具将其转…

【Vue3源码学习】— CH2.7 Computed: Vue 3 计算属性深入解析

Computed: Vue 3 计算属性深入解析 1.计算属性的基本用法2. ComputedRefImpl 类深入解析JavaScript 中的 getter 函数 3. 计算属性的创建:computed 方法解析3.1 源码解析3.2 使用示例 4. 计算属性的工作原理5. 手动实现简化的计算属性6. 结语 在 Vue 3 的响应式系统…

golang 和java对比的优劣势

Golang(或称Go)和Java都是非常流行的编程语言,被广泛应用于各种领域的软件开发。尽管它们都是高级编程语言,但它们具有许多不同的特性和适用场景。本文将重点比较Golang和Java,探讨它们的优势和劣势。 性能方面&#…

Spark实战:词频统计

文章目录 一、Spark实战:词频统计(一)Scala版1、分步完成词频统计2、一步搞定词频统计 (二)Python版1、分步完成词频统计2、一步搞定词频统计 二、实战总结 一、Spark实战:词频统计 (一&#x…

解锁AI提示工程新纪元:你的提问是关键!

文章目录 一、AI的潜力:无尽的宝藏等待解锁二、提问的艺术:挖掘AI潜力的关键三、AI的回应:超越预期的答案与启示四、提问的力量:推动AI不断进步与发展五、用提问开启与AI的智慧对话《向AI提问的艺术:提示工程入门与应用…

RK3562开发板:安卓Linux开发从入门到精通(二)

导读: 通过上篇介绍RK3562的文章我们学习了关于:认识接口、固件下载、安装驱动和烧录工具、烧录固件等内容。这些知识的回顾,希望能够帮助您更好地理解RK3562的使用方法和开发流程。 接下来这篇教程中:我们将重点介绍串口调试、…

[AutoSar]BSW_Memory_Stack_001 存储栈概述

目录 关键词平台说明背景一、存储栈的组成和功能二、名称定义和描述2.1 片上单次最小擦除范围和单次最小写入范围 三、EEPROM(DFLASH)和Flash3.1EEPROM(DFLASH)3.2 Flash 四、实现总览 关键词 嵌入式、C语言、autosar、OS、BSW …

Flutter仿Boss-3.登录页

效果 介绍 在Flutter应用程序中创建登录页面对于用户认证和参与至关重要。登录页面作为用户访问应用程序功能的入口。它应该提供无缝的体验,同时确保安全和隐私。这里仿Boss应用设计的登录页面,我们将创建一个登录页面,允许用户使用手机号码…

第21章-直连路由和静态路由

1. 直连路由 1)定义:指路由器接口直接相连的网段的路由; 2)特点: ① 不需要特别的配置,双UP(物理层+数据链路层); ② 在路由器的接口上配置IP地址即可; ③ 开机自动产生; 2. VLAN间路由 1)需求: 交换机划vlan隔离广播域,在二层无法通信,但三层要实现不同vlan之前…

吴恩达机器学习笔记:第 6 周-11机器学习系统的设计(Machine Learning System Design)11.1-11.2

目录 第 6 周 11、 机器学习系统的设计(Machine Learning System Design)11.1 首先要做什么11.2 误差分析11.3 类偏斜的误差度量 第 6 周 11、 机器学习系统的设计(Machine Learning System Design) 11.1 首先要做什么 在接下来的视频中,我将谈到机器学习系统的设…

【Algorithms 4】算法(第4版)学习笔记 23 - 5.4 正则表达式

文章目录 前言参考目录学习笔记1:正则表达式1.1:表示1.2:快捷表示2:正则表达式与非确定有限状态自动机 REs and NFAs2.1:二元性2.2:模式匹配实现2.3:非确定有限状态自动机 Nondeterministic fin…

python课后习题二

题目: 1. 2. 解题过程: 1. # 有序吗? ls input("请输入一个列表(空格隔开):").split() ls_list list(ls) ls_listnew sorted(ls_list) if ls_listnew ls_list:print("列表已排序&quo…

Autodesk Maya 2025---智能建模与动画创新,重塑创意工作流程

Autodesk Maya 2025是一款顶尖的三维动画软件,广泛应用于影视广告、角色动画、电影特技等领域。新版本在功能上进行了全面升级,新增了对Apple芯片的支持,建模、绑定和角色动画等方面的功能也更加出色。 在功能特色方面,Maya 2025…

【AI数字人】根据音频生成带动画的数字人

这是一个从音频和蒙面手势生成全身人体手势的框架,包括面部、局部身体、手和整体动作。为了实现这一目标,我们首先引入 BEATX (BEAT-SMPLXFLAME),一个新的网格级整体协同语音数据集。 BEATX 将 MoShed SMPLX 身体与 FLAME 头部参数相结合,进一步细化头部、颈部和手指运动的…

DolphinScheduler on k8s 云原生部署实践

文章目录 前言利用Kubernetes技术云原生平台初始化迁移基于Argo CD添加GitOpsDolphinScheduler 在 k8s 上的服务自愈可观测性集成服务网格云原生工作流调度从HDFS升级到S3文件技术总结 前言 DolphinScheduler 的高效云原生部署模式,比原始部署模式节省了95%以上的人…

谷粒商城实战(008 缓存)

Java项目《谷粒商城》架构师级Java项目实战,对标阿里P6-P7,全网最强 总时长 104:45:00 共408P 此文章包含第151p-第p157的内容 简介 数据库承担落盘(持久化)工作 拿map做缓存 这种是本地缓存,会有一些问题 分布…