JAVA每日面经——JVM篇(包含JVM优化)

👩🏽‍💻个人主页:阿木木AEcru

🔥 系列专栏:《Docker容器化部署系列》 《Java每日面筋》

💹每一次技术突破,都是对自我能力的挑战和超越。

一、什么是JVM?

Java虚拟机(JVM)是Java编程语言的核心组件之一,是一个能够执行Java字节码的虚拟机器。它是Java跨平台特性的关键所在,允许Java程序在不同的操作系统上运行,而不需要重新编译成特定平台的机器码。JVM负责将Java源代码编译成字节码,然后在运行时解释或编译执行这些字节码。

二、JVM由什么组成?

  • 程序计数器:是当前线程执行的字节码行号的指示器,用于记录正在执行的虚拟机字节指令地址。它是线程私有的,每个线程都有自己的程序计数器。
  • Java虚拟栈:存放基本数据类型、对象引用以及方法出口等数据。它也是线程私有的,每个线程都有自己的虚拟栈。
  • Native方法栈:与Java虚拟栈相似,但它专门为Native方法服务。也是线程私有的,用于执行本地方法。
  • Java堆:是Java内存中最大的一块,用于存放所有的对象实例和数组。Java堆是垃圾收集器的主要工作区域,所有的垃圾收集都是在这里进行的。Java堆是线程共享的内存区域。
  • 方法区:存放已被加载的类信息、常量、静态变量以及即时编译器编译后的代码数据等。也称为永久代,但在较新的JVM中可能已被元空间所取代。方法区的主要回收目标是常量池的回收和类型的卸载。方法区是各个线程共享的内存区域。

三、JVM 内存为什么要分成新生代,老年代,持久代?

在Java虚拟机中,内存被划分为几个区域,其中包括持久代和堆。持久代主要用于存放方法区和一些其他的数据。而堆则包括了新生代和老年代。

新生代和老年代 Java堆被划分为新生代和老年代。新生代是存放刚创建的对象的地方,而老年代则是存放已经存在一段时间且存活时间较长的对象。

Survivor区的作用 Survivor区主要是为了帮助管理新生代的内存。如果没有Survivor区,新生代的Eden区每次进行垃圾回收时都会把存活的对象移到老年代,这会导致老年代很快被填满,触发大规模的垃圾回收。为了避免这种情况,引入了Survivor区。Survivor区的存在能够减少被送到老年代的对象,进而减少大规模垃圾回收的发生。

为什么要设置两个Survivor区 设置两个Survivor区最主要的目的是为了解决内存碎片化问题。当新生代的Eden区满了之后,存活的对象会被移动到第一个Survivor区。随着新的对象不断被创建和销毁,Eden区和第一个Survivor区的内存会逐渐被占满。当这两个区域再次满了之后,会触发一次垃圾回收,这时会把Eden区和第一个Survivor区中的存活对象移到第二个Survivor区,同时清空Eden区。这个过程的重要性在于,这种移动对象的方式保证了第二个Survivor区中来自Eden区和第一个Survivor区的存活对象在内存中是连续的,避免了内存碎片化的问题。

四、JVM如何优化?

1.1 堆栈相关配置

ruby 复制代码
java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:MaxPermSize=16m -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxTenuringThreshold=0  

解释: -

Xmx3550m:设置最大堆大小为 3550m。
-Xms3550m:设置初始堆大小为 3550m。
-Xmn2g:设置年轻代大小为 2g。
-Xss128k:设置每个线程的堆栈大小为 128k。
-XX:MaxPermSize:设置持久代大小为 16m。
-XX:NewRatio=4:设置年轻代与年老代的大小比值为 1:4(不包括持久代)。
-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值为 1:4。 如果SurvivorRatio为4,则两个Survivor区与一个Eden区的大小比值为 2:4,一个Survivor区占整个年轻代的 1/6。
-XX:MaxTenuringThreshold=0:设置对象在年轻代中的最大年龄。如果设置为0,则年轻代对象不经过Survivor区,直接进入年老代。

1.2 垃圾收集器相关配置

-XX:+UseParallelGC:选择并行垃圾收集器,这种收集器会使用多个线程并行地进行垃圾回收操作。
-XX:ParallelGCThreads=20:配置并行收集器使用的线程数为20,这样可以充分利用多核处理器的性能。
-XX:+UseConcMarkSweepGC:设置年老代使用并发标记-清除收集器,这种收集器允许垃圾回收和应用程序线程同时运行,减少了停顿时间。
-XX:CMSFullGCsBeforeCompaction=5:配置在对年老代进行压缩整理之前触发多少次Full GC。这个参数指定了在进行内存整理之前,需要进行多少次Full GC操作。
-XX:+UseCMSCompactAtFullCollection:开启在Full GC时对年老代进行压缩整理。虽然可能会略微影响性能,但可以帮助消除内存碎片,从而提高内存的利用效率。

五、结尾

感谢您的观看! 如果本文对您有帮助,麻烦用您发财的小手点个三连吧!您的支持就是作者前进的最大动力!再次感谢!

相关推荐
陈阿土i14 分钟前
SpringAI 1.0.0 正式版——利用Redis存储会话(ChatMemory)
java·redis·ai·springai
安全系统学习22 分钟前
【网络安全】Qt免杀样本分析
java·网络·安全·web安全·系统安全
SoFlu软件机器人1 小时前
智能生成完整 Java 后端架构,告别手动编写 ControllerServiceDao
java·开发语言·架构
写bug写bug2 小时前
如何正确地对接口进行防御式编程
java·后端·代码规范
Cyanto2 小时前
Java并发编程面试题
java·开发语言·面试
在未来等你2 小时前
互联网大厂Java求职面试:AI大模型与云原生技术的深度融合
java·云原生·kubernetes·生成式ai·向量数据库·ai大模型·面试场景
sss191s2 小时前
Java 集合面试题从数据结构到 HashMap 源码剖析详解及常见考点梳理
java·开发语言·数据结构
LI JS@你猜啊2 小时前
window安装docker
java·spring cloud·eureka
书中自有妍如玉3 小时前
.net 使用MQTT订阅消息
java·前端·.net