【Java八股】JVM

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

JVM

1. jvm内存区域分为哪些部分

线程私有的:程序计数器、虚拟机栈、本地方法栈

程序计数器:指示当前线程执行到的字节码文件的行号,是线程切换后保证线程能恢复到正确的执行位置的关键

虚拟机栈:用于存储方法调用的数据,由一个个栈帧组成,每个栈帧表示一个方法调用,包括局部变量表、操作数栈、动态链接、方法返回地址。其中局部变量表用于存储基本数据类型的局部变量和对象的引用,操作数栈用于存储中间计算结果,动态链接用于存储方法的符号引用,用于将符号引用转换为调用方法的直接引用。

线程共享的:堆、方法区、直接内存

堆:最大的一块内存区域,唯一目的就是存储对象实例,几乎所以对象实例都在这里分配内存(除了JIT逃逸分析后在栈上分配内存的)。另外堆中还包括字符串常量池。

方法区:JDK1.8以前,方法区是用堆中的永久代实现的,也就是在堆中分配内存,JDK1.8以后方法区是用元空间实现的,也就是在本地内存中。方法区中包括类信息、静态变量、运行时常量池。

直接内存:

2. 堆内存分为哪三个部分,对象是如何在堆中晋升的

新生代内存(Eden区、S0区、S1区)

老生代

永久代(用于实现方法区)

对象首先在Eden区分配内存,年龄为0;

一次垃圾回收后,如果对象还存活,就让它的年龄+1,并将它放在S0或S1;

此后每次垃圾回收后,如果对象还存活,就让它的年龄+1;

如果它的年龄达到15岁,就晋升到老年代。

另外大对象会直接进入老年代,大对象就是需要大量连续内存空间的对象,例如字符串,数组。

3. 运行时常量池是什么

运行时常量池用于存储编译期生成的各种字面量和符号引用

4. Java类加载的过程

1)加载

由类加载器完成,使用哪个类加载器取决于双亲委派模型。这一步骤主要完成了三件事:

根据类名找到二进制字节流;

将二进制字节流的静态存储结构转为方法区中的动态存储结构;

在内存中生成一个代表该类的class对象;

2)验证

确保二进制字节流的信息符合JVM规范

3)准备

为类变量分配内存并设置初始值;

4)解析

将符号引用替换为直接引用。(符号引用相当于仅有名称,不指向具体内存地址,符号引用存储在运行时常量池中,转换为直接引用,即内存实际地址后,才能进行具体访问操作)

5)初始化

执行类的初始化方法,即cinit方法

5. Java对象的创建过程

1)类加载检查

先检查该对象对应的类有没有被加载过,如果没有,先进行类加载过程;

2)分配内存

为对象分配足够的内存,所需内存大小在类加载完成后就可以确定。

分配方式有两种:

第一,指针碰撞

适用于堆内存规整的情况(即没有内存碎片)。用过的内存全部整合到一边,没有用过的内存放在另一边,中间有一个分界指针,只需要向着没用过的内存方向将该指针移动对象内存大小位置即可。

第二,空闲列表

虚拟机会维护一个列表,该列表中会记录哪些内存块是可用的,在分配的时候,找一块儿足够大的内存块儿来划分给对象实例,最后更新列表记录。(这种方式容易造成内存碎片)

3)初始化零值

将分配的内存区域都初始化为零

4)设置对象头

设置对象头信息,包括它属于哪个类、年龄是多少、哈希码是多少等信息。从这里可以看出来,对象的内存分为对象头、实例数据和对齐填充三部分。

5)执行init方法

6. 类加载器是什么,双亲委派模型是什么

类加载器是负责完成类加载的第一步:加载的。每个类都有一个classloader。

直白地说,类加载器就是负责将二进制字节码文件.class文件加载到JVM中,并生成一个class对象。

类加载时不会一次性加载所有的类,而是在用到该类的时候再动态地加载。

类加载器有三种:启动类加载器、扩展类加载器、应用程序类加载器。

启动类加载器是最顶层的加载类,用于加载JDK核心类库。

扩展类加载器用于加载jar包。

应用程序类加载器用于加载用户编写的类。

那么一个类到底由哪个类加载器去加载呢?这是由双亲委派模型指定的。

每个类加载器都有自己对应的父类加载器。

在classloader的loadClass方法中,双亲委派模型的执行流程如下:

1)首先检查该类是否被加载过,如果加载过,直接返回;

2)调用父类加载器的loadClass方法来加载类,这样根据类加载器的父子关系,所有请求最终会传递到顶层的启动类加载器;

3)当父类加载器反馈自己无法加载这个类时(即它没有搜索到这个类),子加载器就尝试自己加载;

4)如果子类加载器也无法加载这个类,就抛出异常;

为什么要使用双亲委派模型?

使用双亲委派模型是为了避免类的重复加载。如果不去调用父加载器的loadClass方法,而是每个类自己加载自己的话,那么如果两个类名字相同,就会出现类名相同但实际上不一样的两个类。

7. 死亡对象的判断方法

引用计数法

  • 每当有一个地方引用它,计数器就加 1;
  • 当引用失效,计数器就减 1;
  • 任何时候计数器为 0 的对象就是不可能再被使用的。

这个方法实现简单,效率高,但是目前主流的虚拟机中并没有选择这个算法来管理内存,其最主要的原因是它很难解决对象之间循环引用的问题。

可达性分析法:

用一系列GC Root作为起点,构建对象的引用链。当进行可达性分析时,从GC Root开始向下搜索,走过的对象即有引用的对象。

而如果从GC Root无法到达对象,就认为此对象是不可用的,需要被回收。

8. 对象的引用类型有哪些

强引用:绝不会被垃圾回收,当JVM内存不足时,即使抛出OOM也不会回收

软引用:可有可无,JVM内存不足时可能会被回收,JVM内存足够就不会被回收

弱引用:只有弱引用的对象,被JVM发现了就会被回收,不管内存是否足够

虚引用:形同虚设,跟没有引用一样,随时可能被回收

9. 如何判断一个常量是废弃常量

假如在字符串常量池中存在字符串 “abc”,如果当前没有任何 String 对象引用该字符串常量的话,就说明常量 “abc” 就是废弃常量,如果这时发生内存回收的话而且有必要的话,“abc” 就会被系统清理出常量池了。

10. 如何判断一个类是无用的类,从而发生类卸载?

类卸载即类的class对象被垃圾回收。

类卸载的条件是:

1)该类的所有实例对象都已经被回收;

2)该类没有在其他任何地方被引用;

3)该类的加载器已经被回收;

11. JVM垃圾回收算法有哪些

1)标记清除算法

标记出所有不需要回收的对象,然后统一回收掉所有没有被标记的。

缺点:效率不高;会产生内存碎片;

2)复制算法

每次仅使用内存区域的一半,这一半使用完后将还存活的对象复制到另一半去,然后将这一半的全部空间清理掉。

缺点:可用内存空间变成了原来的一半,如果对象很大,复制会耗费大量时间。

3)标记整理算法

将存活的对象向一端移动,然后直接清理掉边界以外的全部内存。

缺点:因为要整理,效率也不高,适合老年代这种垃圾回收频率不是很高的场景。

4)分代收集算法

当前虚拟机的垃圾收集都采用分代收集算法,即根据新生代、老年代等分代,选择不同的垃圾收集算法。对于新生代,GC频率比较高、对象占用内存也不是很多的情况,可以选择复制算法。对于老年代,存活几率比较高,可以选择标记清除或者标记整理算法。

实际上JVM之所以对对象进行分代,也是为了垃圾回收时能够根据不同代对象的特点选择合适的算法。

12. 垃圾回收器有哪些

1)Serial串行收集器

历史最悠久的,单线程的,新生代标记复制算法,老生代标记整理算法

2)Serial Old

Serial收集器的老年代版本

3)并行收集器ParNew

其实就是Serial的多线程版本,仍然是新生代标记复制算法,老生代标记整理算法

4)Parallel Scavenge

JDK1.8采用的收集器。同样新生代标记复制算法,老生代标记整理算法,且为多线程。但提供了很多参数帮助用户实现最大吞吐量

5)Parallel Old

Parallel Scavenge的老年代版本

6)CMS收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用。

7)G1收集器

G1 (Garbage-First) 是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征。

12. JVM常用的参数有哪些

指定堆内存大小:-Xms用于指定最小堆内存大小,-Xmx用于指定最大堆内存大小

指定新生代内存:-XX:NewSize最小新生代内存, -XX:MaxNewSize最大新生代内存,-Xmn直接指定新生代内存大小,另外还可以通过-XX:NewRation指定新生代老生代内存比例

指定元空间大小:-XX:MetaspaceSize、-XX:MaxMetaspaceSize

选择垃圾回收器:-XX:+UseSerialGC选择串行收集器、-XX:+UseParallelGC选择并行收集器、-XX:+UseConcMarkSweepGC选择CMS收集器、-XX:+UseG1GC选择G1收集器

还有一些打印日志的参数:

-XX:+PrintGCDetails 打印GC信息

-XX:+PrintGCDateStamps 打印GC信息

-XX:+PrintTenuringDistribution # 打印对象分布

-XX:+PrintHeapAtGC # 打印堆数据

把对讲门铃(控制底楼铁门)接入米家服务器 今天讲个跟SDR或者无人机无关的东西,技术含量不高,但是方便了我的生活。 现在家门有智能锁,汽车也可以远程解锁发动,NFC门禁也可以用某些手机复制,唯独楼下的铁门,必须用老式对讲门铃控制。 也就是说其它钥匙都可以不带,就剩这个钥匙还必须随身携带。 另外有时候人不在家,不能开楼下铁门,快递员也没法把东西送上楼。 ...... 阅读详情

相关推荐

别再一个个BAPI调了!用CVI_EI_INBOUND_MAIN一次性搞定SAP BP主数据(附完整ABAP代码)

本文详细介绍了如何使用SAP标准函数CVI_EI_INBOUND_MAIN高效维护业务伙伴(BP)主数据,替代传统的多BAPI调用方式。通过完整ABAP代码示例,展示了如何一站式处理供应商、客户、公司代码等所有视图的创建与更新,提升数据一致性和开发效率。

weixin_29204205的博客 264

java八股文之JVM

线程共享的区域:主要用来保存对象实例,数组等,内存不够则抛出OutOfMemoryError异常。组成:年轻代+老年代– 年轻代被划分为三部分,Eden区和两个大小严格相同的Survivor区,一个对象在Eden区存活后就会放入Survivor区– 老年代主要保存生命周期长的对象,一个对象在多次Survivor区存活后就会放入老年区Jdk1.7和1.8的区别– 1.7中有有一个永久代,存储的是类信息、静态变量、常量、编译后的代码。

qq_45923849的博客 2337

iTerm2+oh-my-zsh最全配置

iTerm2+oh-my-zsh最全配置安装前先看效果图一.安装[iTem2](https://iterm2.com/)二.安装[oh-my-zsh](https://ohmyz.sh/)三.安装[Powerline](https://powerline.readthedocs.io/en/latest/installation.html)四.安装 [Meslo](https://github.com/powerline/fonts) 字体库五.安装agnoster主题六.安装语法高亮七.安装代码补全插件八

xinximo的博客 2589

java八股文-jvm

加载某一个类,先委托上一级的加载器进行加载,如果上级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载该类.

qq_40784183的博客 1334

Java八股文——JVM

本文整理了Java面试中常见的与JVM相关的问题,包括JVM介绍、GC、JVM调优等。

郎逸的博客 1240

Java八股文总结】之JVM

JavaJVM相关面试知识总结

qq_46111316的博客 2167

JVMJava八股文之JVM

JVM

Hanson的博客 1369

JAVA学习】关于对Java八股文之JVM的总结

JVMJava Virtual Machine,Java虚拟机)是一个可以执行Java字节码的虚拟计算机。它是Java平台的核心组件之一,使得Java能够实现“一次编写,到处运行”(Write Once, Run Anywhere,WORA)的目标。以下是JVM的一些关键特性:跨平台性JVMJava字节码提供了一个运行时环境,使得Java程序可以在任何安装了相应JVM的平台上运行,而不需要重新编译。内存管理JVM负责自动管理程序的内存,包括对象的创建和垃圾回收(GC)。执行引擎。

xiaoxie8023的博客 1029

Java面试八股文(JVM篇)(❤❤)

JVM内存管理最大的一块,对被线程共享,目的是存放对象的实例,几乎所欲的对象实例都会放在这里,当堆没有可用空间时,会抛出OOM异常.根据对象的存活周期不同,JVM把对象进行分代管理,由垃圾回收器进行垃圾的回收管理。JMM是定义程序中变量的访问规则,线程对于变量的操作只能在自己的工作内存中进行,而不能直接对主内存操作.由于指令重排序,读写的顺序会被打乱,因此JMM需要提供原子性,可见性,有序性保证.Java自带的加载器加载的类,在虚拟机的生命周期中是不会被卸载的,只有用户自定义的加载器加载的类才可以被卸.

与海 1326

Java八股文(JVM

java虚拟机jvm

qq_63635361的博客 1686

java八股jvm

从下往上找,有同名类优先使用上级加载器的,不用自己的,父加载器没有就加载自己的。年轻代会使用复制算法,清理效率高。

m0_50973548的博客 900

面试鸭Java八股JVM

Java 虚拟机面试题。

小小博客 873

Java面试八股文-JVM

1、JVM的基本结构 JVM由三个主要的子系统构成: 类加载器子系统 运行时数据区(内存结构) 方法区 虚拟机栈 本地方法栈 堆 程序计数器:记住下一条JVM指令的执行地址 执行引擎 2、JVM的类加载过程、机制,每个过程的作用 系统加载 Class 类型的文件主要有三步:加载->连接->初始化。连接过程又可分为三步:验

sinat_38779719的博客 1226

JAVA面试八股文之JVM

java虚拟机对于多线程是通过线程轮流切换并且分配线程执行时间。在任何的一个时间点上,一个处理器只会处理执行一个线程,如果当前被执行的这个线程它所分配的执行时间用完了【挂起】。处理器会切换到另外的一个线程上来进行执行。并且这个线程的执行时间用完了,接着处理器就会又来执行被挂起的这个线程。​ 那么现在有一个问题就是,当前处理器如何能够知道,对于这个被挂起的线程,它上一次执行到了哪里?那么这时就需要从程序计数器中来回去到当前的这个线程他上一次执行的行号,然后接着继续向下执行。​。

m0_59230408的博客 1万+

Java面试题、八股文学习之JVM

最新版面试题——JVM篇,持续更新中.......

guihong004的博客 1858

JAVA八股--JVM

被native关键字修饰的方法就是本地方法例如:new Object().hashCode() 获取对象内存地址 涉及到读取内存IO中读文件(输入文件 操作硬盘) new FileInputStream("").read();读硬盘中的数据启动线程 new Thread().start();启动线程 就是把这个线程注册到操作系统垃圾是指在程序运行中,没有任何引用指向的对象,这个对象就称为垃圾对象。如果垃圾对象不清理,后来的对象就可能没有地方存放,进而导致内存溢出。

2301_77205900的博客 855

Java八股文——JVM

有关jvmjava八股文,内容详细,简单易懂

PjhDepon的博客 3900

Java八股面试指南:掌握JVM、并发与Spring核心考点

技术面试中,基础知识的掌握程度是衡量开发者水平的重要标尺。在Java方向,JVM内存模型、并发编程、Spring框架、MySQL索引与事务等核心概念,构成了技术面试的高频考点。理解这些技术背后的设计原理——如垃圾回收算法、锁升级机制、Bean生命周期、MVCC并发控制——不仅能够从容应对面试官的层层追问,也能在实际项目中指导性能优化与问题定位。从构建知识框架到结合项目实践,系统化的准备方式远比机械背诵千题更有效。围绕Java八股现象,深入剖析其成因与核心考点,梳理答题逻辑与备战策略,有助于求职者从刷题焦虑中

weixin_32705179的博客 308

java八股文】之JVM基础篇

java八股文】之JVM基础篇

一个老码农 1694

Java 面试 八股文】JVM 虚拟机篇

线程私有的,内部保存的字节码的行号。用于记录正在执行的字节码指令的地址。javap -verbose xx.class 打印堆栈大小,局部变量的数量和方法的参数。难易程度:☆☆☆出现频率:☆☆☆☆线程共享的区域:Java堆 (Heap) 是Java虛拟机中内存管理的一个重要区域,主要用于存放对象实例和数组。当堆中没有内存空间可分配给实例,也无法再扩展时,则抛出OutOfMemoryError异常。

Luo_LA的博客 1961

java八股文面试[JVM]——JVM参数

Xss 为jvm启动的每个线程分配的内存大小,默认JDK1.4中是256K,JDK1.5+中是1M。:给定-Xms Xmx -Xmn 问 最大的eden区域是多少M。怎么对jvm进行调优?

u200814342A的博客 1103

Java八股文面试 | JVM篇 】

本文聚焦 JVM 高频面试题,涵盖Java运行时数据区,类的双亲委派机制,详解垃圾回收算法与垃圾回收器。

2025CSDN博客之星Top246,后端开发技术领域新星创作者。 1848
上一篇: Java集合+并发(部分)
拍坛对酒
博客等级 码龄6年 83粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值