👩🏽‍💻个人主页:阿木木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 堆栈相关配置

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时对年老代进行压缩整理。虽然可能会略微影响性能,但可以帮助消除内存碎片,从而提高内存的利用效率。

五、结尾

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

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐