Java八股文总结三

news2024/9/27 5:46:17

JVM部分

一、JVM是由哪几部分组成的

  1. 类加载器
  2. 运行时数据区
  3. 执行引擎
  4. 本地库接口 

说一下运行时数据区的组成:

本地方法栈、虚拟机栈、堆区、程序计数器、方法区。

虚拟机栈帧的组成:

每个栈帧包含五部分,分别包括局部变量表、操作数栈、动态链表(指向运行时常量池的方法引用)、方法返回地址和一些附加信息。

详细参考:JVM——运行时数据区域_jvm运行时数据区-CSDN博客

什么是元空间(方法区的实现):

元空间是一块本地内存,它用于存放类的元数据,例如类名、访问修饰符、字段、方法、注解等信息。这些信息在程序运行期间保持不变,存储在元空间中可以提高程序的运行效率。元空间由Java虚拟机主动管理,可以将其看作是一块特殊的堆内存。

详细参考: JVM--方法区&元空间_元空间和方法区的区别-CSDN博客

二、堆和栈的区别

参考文章: 一文读懂堆与栈的区别_堆栈-CSDN博客

三、对象是如何创建的,创建对象如何解决并发问题

参考文章:关于JVM对象创建与内存分配机制_java jvm生成大对象 会怎么样-CSDN博客

 四、如何定位到内存中的对象,对象在内存中是怎么存在的

定位内存的对象

java 程序需要通过栈上的 reference 数据来操作堆上的具体对象。由于reference 类型在JVM 规范中只规定了一人指向对象的引用,并未定义这个引用如何定位和访问具体位置,所以对象访问方式由具体虚拟机实现而定。目前主流的访问方式有句柄和直接指针两种。

  • 直接指针,java堆对象的布局中就必须考虑如何放置访问方法区中类型数据的相关信息。
  • 句柄访问,java 堆中将会划分出一块内存来作为句柄池,reference 中存储的就是对象的句柄地址,而句柄中包含了对象实例和类型数据各自的具体地址信息。

二者各有优势,使用句柄访问这样做的好处是中 reference 存储的句柄地址较为稳定,因为在Java 堆中进行了垃圾回收,对象的地址发生了改变的时候,只需要修改句柄的对象实例数据指针就行。而使用直接指针的最大好处就是速度更快。

对象的内存布局: 

对象在堆内存的内存布局主要有三部分,即对象头、实例数据以及对其填充。
对象头

对象头主要包含两部分的内容,一个叫做运行时元数据(MarkWord),一个叫做类型指针 (CIass MetadataAddress)。

类型指针指向元数据区代表当前类的 class 对象,确定该对象所属的类型,而运行时元数据又包含了:

  • 哈希值(hashcode)也就是对象在堆空间中都有一个首地址值,栈空间的引用根据这个地址指向堆中的对象这就是哈希值起的作用;
  • GC 分代年龄: 对象首先是在Eden中创建的,在经过多次GC后,如果没有被进行回收,就会在 survivor 中来回移动,其对应的年龄计数器会发生变化,达到闽值后会进入养老区,
  • 锁状态标志: 在同步中判断该对象是否是锁:
  • 线程持有的锁;
  • 线程偏向ID;
  • 偏向时间戳。

实例数据

它是对象真正存储的有效信息,包括程序代码中定义的各种字段类型,当然也包含从父类继承下来的字段。注意这里有一些规则: 相同宽度的字段总是被分配在一起,父类中定义的变量会出现在子类之前,因为父类的加载是优先于子类加载的。

对齐填充:没有特殊含义,仅仅起到占位符的作用。

五、内存溢出与内存泄漏问题

内存泄漏 : 泄漏对象无法被GC
内存溢出 : 内存对象确实还应该存活。此时要根据JVM堆参数与物理内存相比较检查是否还应该把JVM 堆内存调大;或者检查对象的生命周期是否过长。

六、什么是垃圾回收系统?哪些内存区域需要回收?

在Java中,垃圾回收(Garbage Collection,简称GC),是自动管理内存的机制。它负责检测不再使用的对象,并释放它们所占用的内存,以供其他对象使用。

参考文章:关于JVM垃圾回收机制_java垃圾回收可回收区域-CSDN博客

七、如何判断对象是否可以回收,GC Roots对象有哪些,对象的回收过程?

参考文章:

Java中垃圾回收机制中如何判断对象需要回收?常见的 GC 回收算法有哪些?_java 中垃圾回收机制中如何判断对象需要回收?常见的 gc 回收算法有哪些?-CSDN博客

 八、方法区能否被回收 

方法区中回收的对象包括两部分,不被引用的常量以及不被使用的类型。

    已经没有任何字符串对象引用常量池中的“java”常量,且虚拟机中也没有其他地方引用这个字面量。如果在这时发生内存回收,而且垃圾收集器判断确有必要的话,这个“java”常量就将会被系统清理出常量池。

    判定一个类型是否属于“不再被使用的类”的条件就比较苛刻了。需要同时满足下面三个条件:
    ·该类所有的实例都已经被回收,也就是Java堆中不存在该类及其任何派生子类的实例。
    ·加载该类的类加载器已经被回收,这个条件除非是经过精心设计的可替换类加载器的场景,如OSGi、JSP的重加载等,否则通常是很难达成的。
    ·该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

九、四种引用类型

 参考文章:

(一)四种引用类型_引用类型有哪四种-CSDN博客

 十、请问了解Minor GC和Full GC么,这两种GC有什么不⼀样吗

  1. Minor GC又称为新生代GC : 指的是发生在新生代的垃圾收集。因为Java对象大多都具备朝生夕灭的特性,因此Minor GC(采用复制算法)非常频繁,一般回收速度也比较快。
  2. Full GC又称为老年代GC或者Major GC : 指发生在老年代的垃圾收集。出现了Major GC,经常会伴随至少⼀次的Minor GC(并非绝对,在Parallel Scavenge收集器中就有直接进行Full GC的策略选择过程)。Major GC的速度⼀般会比Minor GC慢10倍以上。

十一、有哪些垃圾回收算法?新生代为划分空间的比例

垃圾回收算法:标记-清除、标记-复制、标记-整理,分代算法。

新生代划分空间比例:

一个 Eden区,两个survivor区,eden区占80%内存空间,每一块survivor区占 10%。平时使用一块eden和一块survivor区所以内存使用率为 90%。

参考文章:新生代的垃圾回收算法_新生代垃圾回收算法-CSDN博客

十二、常见的垃圾回收器,CMS是如何工作的,G1收集器是如何工作的

CMS

CMS收集器是基于“标记—清除”算法实现的,它的运作过程相对于前面几种收集器来说更复杂一 些,整个过程分为4个步骤:
初始标记(CMS initial mark)
初始标记仅仅只是标记⼀下GC Roots能直接关联到的对象,速度很快,需要“Stop The World”。
并发标记(CMS concurrent mark)
并发标记阶段就是进行GC Roots Tracing的过程。
重新标记(CMS remark)
重新标记阶段是为了修正并发标记期间因用户程序继续运作而导致标记产生变动的那一部分对象的 标记记录,这个阶段的停顿时间⼀般会比初始标记阶段稍长⼀些,但远比并发标记的时间短,仍然 需要“Stop The World”。
并发清除(CMS concurrent sweep)
并发清除阶段会清除对象。

详细参考:史上最经典垃圾回收器(CMS,G1)详解、适用场景及特点、使用命令_cms垃圾回收器-CSDN博客

十三、触发GC的条件

一、Minor GC触发条件:

    当Eden区满时,触发Minor GC。

二、Full GC触发条件:

  1. 调用System.gc()时,系统建议执行Full GC,但是不必然执行
  2. 老年代空间不足
  3. 方法区空间不足
  4. 年轻代对象总大小大于老年代可用空间大小,或历史Minor GC后进入老年代的对象平均大小大于老年代可用空间大小(与空间分配担保机制有关)
  5. 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代。

参考文章: jvm中触发GC的条件_jvm gc触发条件-CSDN博客

十四、什么是三色标记?什么是多标和漏标? 如何解决漏标问题?

 详细文章:JVM - 你们垃圾回收器用的什么? G1有哪些特点?G1如何实现可预测的停顿时间?漏标问题如何解决的?介绍下三色标记?说说STAB 算法 ?_stab算法-CSDN博客

十五、什么是类加载机制,讲讲类加载过程

Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转化解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。

与编译时需要进行连接的语言不同,在Java语言里,类的加载、连接和初始化过程都是程序运行期间完成的,Java天生可以动态扩展的语言特性就是依赖运行期间动态加载和动态连接这个特点来实现的。例如,编写一个面向接口的应用程序,可以等到运行时再指定其 实际的实现类,用户可以通过Java预置的或自定义类加载器,让某个本地的应用程序在运行时从网络 或其他地方上加载一个二进制流作为其程序代码的一部分。

类加载过程

其中类加载的过程包括了加载、验证、准备、解析、初始化五个阶段。 在这五个阶段中,加载、验证、准备和初始化这四个阶段发生的顺序是确定的,而解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也成为动态绑定或晚期绑定)。另外注意这里的几个阶段是按顺序开始,而不是按顺序进行或完成,因为这些阶段通常都是互相交叉地混合进行的,通常在一个阶段执行的过程中调用或激活另一个阶段。

    一、加载:就是指将class文件读入内存,并为之创建一个Class对象。任何类被使用时系统都会建立一个Class对象。

    二、连接:包括以下三个步骤

  1. 验证:是否有正确的内部结构,并和其他类协调一致
  2. 准备:负责为类的静态成员分配内存 (所使用的内存都将在方法区中进行分配),并设置默认初始化值 (注意这里并没有指定具体的值,只是默认值,比如int是0,boolean是false。指定具体的值那是在类的初始化。但是,如果是static final静态常量,则直接指定具体的值!)
  3. 解析:将常量池内的符号引用替换为直接引用

    三、初始化,为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化。在Java中对类变量进行初始值设定有两种方式:

    ①声明类变量并指定初始值

    ②使用静态代码块为类变量指定初始值

 详细文章:10. 类加载机制-CSDN博客

值得你收藏的类加载、初始化、实例化、加载时机,初始化时机..._全局变量直接new会在类加载时实例化吗-CSDN博客

十六、 类加载时机、类初始化顺序

类加载时机

类加载器并不需要等到某个类被“首次主动使用”时再加载它,JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误(LinkageError错误)如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误

所以什么情况下虚拟机需要开始加载一个类呢?虚拟机规范中并没有对此进行强制约束,这点可以交给虚拟机的具体实现来自由把握。

 类初始化顺序

 参考文章:Java类加载机制、初始化顺序_java的jar包中的类和应用中的类初始化顺序-CSDN博客

十七、什么是类加载器,有哪些类加载器

类加载器:类加载器(Class Loader)是Java虚拟机(JVM)的一部分,负责将Java类的二进制代码加载到内存中,并转换为可执行的Java字节码。它是Java语言的重要特性之一,为Java应用程序提供了动态加载和运行时扩展的能力。

类加载器主要有以下几种类型:

  1. 启动类加载器:加载 JDK 中 lib 目录中 Java 的核心类库,即$JAVA_HOME/lib目录。
  2. 扩展类加载器。加载 lib/ext 目录下的类。
  3. 应用程序类加载器:加载我们写的应用程序。
  4. 自定义类加载器:根据自己的需求定制类加载器。

详细参考文章: 什么是类加载器,类加载器有哪些-CSDN博客

十八、什么是双亲委派模型, 如何破坏双亲委派模型

什么是双亲委派模型?

当一个类需要加载时,类加载器会根据一定的加载规则进行类加载工作。一般情况下,类加载器会先委托父加载器来尝试加载类只有当父加载器无法加载时,才由子加载器尝试加载。这种机制被称为"双亲委派模型"。这种模型保证了类的加载是从上到下的,避免了重复加载和类的版本冲突问题。

 如何破坏双亲委派模型:

双亲委派机制是Java虚拟机(JVM)的一个特性,它确保了类的唯一性和安全性。这个机制的核心思想是,当一个类加载器要加载一个类时,它首先会委托给它的父类加载器去尝试加载这个类,只有当父类加载器无法完成这个任务时,它才会尝试自己去加载这个类。

破坏双亲委派机制通常是不被推荐的行为,因为它可能会导致类的唯一性无法保证,从而引发一些安全问题。然而,出于学习或特定场景的需要,了解如何绕过这个机制也是有价值的。以下是一些可能破坏双亲委派机制的方法:

  • 自定义类加载器: 通过继承ClassLoader类并重写loadClass方法,可以创建一个自定义的类加载器。在这个方法中,可以忽略双亲委派机制,直接从文件系统或者网络加载类。
  • 使用线程上下文类加载器: 在某些情况下,可以通过设置线程的上下文类加载器来改变类加载的行为。通过设置不同的类加载器,可以加载同名但不同的类。
  • 使用URLClassLoader: URLClassLoader允许从指定的URL加载类,它不遵循双亲委派模型,而是直接加载类。
  • 使用系统类加载器加载: 通过使用系统类加载器(ClassLoader.getSystemClassLoader())加载类,可以绕过双亲委派机制。
  • 代理类加载器: 创建一个代理类加载器,它在加载类时,可以决定是否调用父类加载器。
  • 使用反射: 在某些情况下,可以使用反射API来加载类,但这通常不会破坏双亲委派机制。
  • 修改JVM实现: 如果你有JVM的源代码,可以修改JVM的实现,从而改变类加载的行为。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【鸿蒙开发从0到1 day06】

一.视口 视口:用来约束html,html和设备的大小进行适配 (注释视口) 添加视口 二倍图 概念:设计稿里面每个元素的尺寸的倍数 作用:防止图片在高分辨率屏幕下模糊失真 可以使用pxcook 如果我们的原图大小是设计图的两倍,可以使用pxCook去原图抓取到设…

墨刀基础篇(一):全局事件和动效

一:全局事件 全局事件是针对于整个页面设置的,而不是针对页面中的某个组件设置的。 事件 手势事件: 单击左滑、又滑、上滑、下滑、长按、双击摇一摇 鼠标事件: 单击、双击长按鼠标移入、鼠标移出右键 定时事件 定时器 行为 …

C++11第一弹:简介 | 统一的列表初始化 | 声明

🌈个人主页: 南桥几晴秋 🌈C专栏: 南桥谈C 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据…

盘点2024年最常用的透明加密软件!TOP10排行榜

随着数字化生活的深入,数据安全成为每个人和企业都不可忽视的重要议题。透明加密软件因其在保障数据安全的同时,不影响用户日常操作的特性,越来越受到人们的青睐。以下是2024年最常用的透明加密软件TOP10排行榜,它们以卓越的性能和…

Vue3 使用 富文本编辑器 wangeditor/editor-for-vue 配置详解

Vue3 使用 富文本编辑器 wangeditor/editor-for-vue 配置详解 先上官网地址 wangEditor 5 点这里 wangeditor 主要API 配置功能栏 let toolbarConfig {toolbarKeys: [ "bold", // 字体加粗 "underline", // 字体下划线 "italic", // 字体斜体…

一款用于分析java socket连接问题的工具

network-tools 介绍 network-tools基于sun jdk、Oracle jdk开发,拦截基于java socket请求,它包括 ​ http 客户端 ​ jdbc 客户端 ​ mq 客户端 ​ redis 客户端 目前提供如下功能: ​ 最近端点连接情况 ​ 最近与远程端点连接情况&am…

公寓项目(尚庭公寓笔记)

公寓项目 课程介绍项目概述移动端业务功能后台管理系统业务功能-公寓管理后台管理系统业务功能-租赁功能后台管理系统业务功能-系统管理&用户管理核心业务功能技术概述 项目开发流程项目原型数据库设计理论ER模型数据库设计流程 数据库设计实操概念模型逻辑模型公寓信息房间…

sse fetch-event-source插件的使用

sse简单介绍https://blog.csdn.net/weixin_42400404/article/details/141895877?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22141895877%22%2C%22source%22%3A%22weixin_42400404%22%7D fetch-event-source gitHub地址 通信…

快速构建 AI 应用的利器:Python 库 Mesop

在当今这个 AI 技术飞速发展的时代,开发者们总是希望能够更快、更便捷地构建 AI 应用程序。今天,我要给大家介绍一个由 Google 推出的 Python 库——Mesop。它的出现,让我们能够轻松地搭建高效的 AI 应用。 Mesop 是什么? Mesop …

C#如何使用外部别名Extern alias

说到 extern 关键字,只是很简单告诉大家用来做区分两个不同 dll 有相同的命名空间和类,可以使用这个关键字。 在遇到了存在两个 dll 都有相同的命名空间,而且有相同的类的时候,如何同时使用这两个 dll 的类。 这里有两个库 Jall…

4.4SQL注入之布尔盲注

SQL注入之布尔盲注1.什么是布尔盲注? Web的页面的仅仅会返回True和False。那么布尔盲注就是进行SQL注入之后然后根据页面返回的True或者是False来得到数据库中的相关信息。 返回False时: 返回True时: 2.如何进行布尔盲注? 注入…

把空格对应的表头拼接起来

某Excel表格有表头,部分数据格为空。 ABCDEF1stat Astat Bstat Cstat Dstat Estat F2113XX4XXXX56XXX7XXXX8XX 要求处理每行,把空数据格对应的表头用斜线拼起来。 H1Summary2stat B/stat C/stat E/stat F/3stat C/stat D/stat F/4stat B/stat E/5stat…

冒泡排序及qsort函数

文章目录 前言一、冒泡排序二、qsort函数 前言 冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复进行的,直到没有再需要交换的元素&#xff…

软考证书补贴动不动就好几万,真的能领到吗?

取得软考证书在许多地区都有补贴政策,从几千至二十几万元不等。有些考生会好奇这些补贴是真的能领到吗,为此,小希搜集了一些例子证明是可以领到的,供大家参考。 1、奖励名单里的软考证书 在一些地区公示的奖励名单里,…

SpringBoot使用入门

springboot基础 1. 项目创建(1) idea自动创建(2) 手动创建①创建普通maven项目② 引入springboot依赖 2. 配置文件使用(1) 配置文件格式(2) 配置文件书写(3) 值的获取 3. bean的管理(1) bean的扫描(2) bean的注册Bean注解Import注解 自定义组合注解减少配置类注解(3) 条件注册b…

vue3-scroll-seamless 大屏无缝滚动

npm install vue3-scroll-seamless --save //或者 yarn add vue3-scroll-seamless页面中引入 <template><div class"safety_item"><SoftwareHead title"高危及以上组件漏洞TOP10"></SoftwareHead><div class"table"…

python学习12:对txt/text类型的文件进行读写

1.对txt类型的文件进行读写 1&#xff09;对text文件的操作 打开文件-读/写文件-关闭文件 1.1)打开文件 open() 1.2)读/写文件 读: read(),readline(),rendlines() 写:write() 1.3)关闭文件 close() # 案例1:(读):moder # filename test004.txt # 同一个文件夹 filename rD:…

Unity之获取Avpro视频画面并在本地创建缩略图

一、效果 功能需求&#xff1a;获取StreamingAssets文件夹下的所有视频&#xff08;包含其子文件夹&#xff09;&#xff0c;获取指定时间的视频画面&#xff0c;然后将图片保存到本地磁盘中。 二、关于Avpro的事件监听 当指定视频时间进度时会触发FinishedSeeking&#xff0c…

[论文笔记]RAFT: Adapting Language Model to Domain Specific RAG

引言 今天带来一篇结合RAG和微调的论文&#xff1a;RAFT: Adapting Language Model to Domain Specific RAG。 为了简单&#xff0c;下文中以翻译的口吻记录&#xff0c;比如替换"作者"为"我们"。 本文介绍了检索增强微调(Retrieval Augmented Fine Tunin…

CNN-LSTM用于时间序列预测,发二区5分+没问题!

为了进一步提高时序预测的性能&#xff0c;研究者们组合了CNN和LSTM的特点&#xff0c;提出了CNN-LSTM混合架构。 这种架构因为独特的结构设计&#xff0c;能同时处理时空数据、提取丰富的特征、并有效解决过拟合问题&#xff0c;实现对时间序列数据的高效、准确预测&#xff…