JVM常用启动参数解析

关于JVM 启动参数的配置, Java 运行时环境的内存、垃圾回收、日志等方面的行为。
下面是各个参数的含义:

-Xmn600m:新生代内存大小为 600MB。
-Xms2048m:堆内存初始大小为 2048MB。
-Xmx2048m:堆内存最大大小为 2048MB。
-XX:MetaspaceSize=128m:元空间初始大小为 128MB。
-XX:MaxMetaspaceSize=256m:元空间最大大小为 256MB。
-XX:+UseParNewGC:使用并行化的新生代垃圾回收器。
-XX:+UseConcMarkSweepGC:使用并发标记清除垃圾回收器。
-verbose:gc:在控制台输出 GC 日志。
-XX:+PrintGCDetails:打印 GC 详细信息。
-XX:+PrintGCDateStamps:打印 GC 发生的日期时间。
-XX:+PrintGCTimeStamps:打印 GC 发生时的时间戳。
-XX:+PrintTenuringDistribution:打印对象年龄分布情况。
-Xloggc:/data/logs/java-op-adslot-admin/gc.log:将 GC 日志输出到指定文件。
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector:使用异步日志记录器。
-XX:+HeapDumpOnOutOfMemoryError:当发生 OutOfMemoryError 错误时,自动生成堆转储文件。
-XX:HeapDumpPath=/data/logs/java-op-adslot-admin:设置堆转储文件的输出路径。
-XX:+PrintCommandLineFlags:在启动时打印出所有的 JVM 参数。

这些参数可以根据应用程序的特点和运行环境进行调整,以提高性能、稳定性和可靠性。

-Xmn600m:新生代内存

  • 堆内存被划分为新生代(Young Generation)和老年代(Old Generation)两个部分。新生代是用于存放新创建的对象的一块内存区域,通常包括 Eden 区、Survivor 0 区和 Survivor 1 区三个部分。
  • 当程序创建一个新对象时,它会被分配到 Eden 区。当 Eden 区满时,Java 垃圾回收器会对其中的对象进行垃圾回收,并将仍然存活的对象移动到 Survivor 0 区。如果 Survivor 0 区也满了,那么垃圾回收器会再次对其中的对象进行垃圾回收,并将仍然存活的对象移动到 Survivor 1 区。在下一次垃圾回收时,存活时间较长的对象会被移动到老年代中。
  • 由于新生代中的对象通常具有较短的生命周期,因此使用专门的垃圾回收算法来处理新生代可以提高垃圾回收效率。通常情况下,新生代使用的垃圾回收算法包括 Serial、ParNew 和 G1 等。在 JVM 启动时,可以使用 -Xmn 参数来指定新生代的大小,以控制新生代中的对象数量和垃圾回收的频率。

Xms2048m:堆内存

  • 在 Java 中,堆内存(Heap Memory)是用于存放对象实例的一块内存区域。Java 程序中所有的对象都存储在堆内存中,包括通过 new 关键字创建的对象、数组对象等等。
  • 堆内存的大小可以通过启动时的 JVM 参数来配置。通常情况下,堆内存的大小会根据应用程序的需求而动态调整。当堆内存不足以容纳新的对象时,Java 垃圾回收器会自动进行垃圾回收,并尝试释放一些无用的对象占用的内存空间。
  • 由于 Java 运行时环境对堆内存的管理是自动的,因此开发者不需要手动分配和释放内存,这是 Java 的一个重要特性之一。同时,也需要注意避免出现内存泄漏等问题,以确保程序的稳定性和可靠性。
  • 元空间(Metaspace)是 JDK 8 中引入的一种新的内存区域,用于存储类和元数据。在早期版本的 JDK 中,类和元数据通常存储在永久代(Permanent Generation)中,但由于永久代的大小固定且难以调整,可能会导致内存溢出等问题。

-XX:MetaspaceSize=128m:元空间

  • 元空间与永久代不同,它使用本地内存(Native Memory)来存储类和元数据,并且具有动态调整大小的能力,因此可以更好地适应不同的应用程序需求。在默认情况下,元空间的大小受系统内存限制,并且可以通过启动时的 JVM 参数进行配置。
  • 使用元空间还有一个好处是,它可以避免永久代中经常出现的 PermGen 内存溢出问题。在元空间中,当内存不足时,JVM 会触发垃圾回收并自动释放一些无用的类和元数据占用的内存空间,从而避免了内存泄漏等问题。
  • 需要注意的是,在 JDK 9 中,永久代已被完全移除,并且元空间成为了 Java 类和元数据的唯一存储区域。

-XX:+UseParNewGC:使用并行化的新生代垃圾回收器

  • 并行化的新生代垃圾回收器(Parallel New Garbage Collector)是一种用于处理新生代内存的垃圾回收器。它采用多线程并行地进行垃圾回收,以提高垃圾回收效率。
  • 在并行化的新生代垃圾回收器中,新创建的对象首先被分配到 Eden 区域。当 Eden 区域满时,JVM 会启动一个垃圾回收线程,将不再使用的对象清除掉,并将存活的对象移动到 Survivor 区域。当 Survivor 区域也满了之后,JVM 会将存活的对象移动到另一个 Survivor 区域中,并清空原来的 Survivor 区域。如果两个 Survivor 区域都被填满了,则会触发一次完整的垃圾回收,将存活的对象移动到老年代中。
  • 与串行化的新生代垃圾回收器相比,并行化的新生代垃圾回收器可以利用多个 CPU 核心来并行执行垃圾回收,从而显著提高垃圾回收的效率。同时,由于并行化的新生代垃圾回收器只对新生代内存进行垃圾回收,因此对应用程序的暂停时间影响较小,适用于需要高吞吐量的场景。

-XX:+UseConcMarkSweepGC:使用并发标记清除垃圾回收器

  • 使用并发标记清除垃圾回收器(Concurrent Mark Sweep Garbage Collector,简称 CMS GC)是一种用于处理老年代内存的垃圾回收器。它采用并发的方式进行标记和清除操作,以减少应用程序的暂停时间,提高系统的响应速度。
  • 在使用并发标记清除垃圾回收器时,JVM 会在后台启动一个垃圾回收线程来执行标记和清除操作。首先,垃圾回收器会对老年代中的对象进行标记,以确定哪些对象是存活的。在标记过程中,应用程序可以继续运行,不需要暂停等待垃圾回收完成。
  • 接着,在标记完成后,垃圾回收器会对已经标记的对象进行清除操作,将不再使用的对象回收掉,释放占用的内存空间。在清除过程中,应用程序也可以继续运行,不需要等待垃圾回收完成。
  • 与串行化或并行化的垃圾回收器相比,使用并发标记清除垃圾回收器可以大大减少应用程序的暂停时间,提高系统的响应速度。但是,由于并发标记清除垃圾回收器需要占用一定的 CPU 和内存资源,因此可能会对应用程序的性能产生一定的影响。

对象年龄分布

  • 对象年龄分布指的是在 Java 垃圾回收过程中,存活对象的年龄分布情况。在新生代内存中,对象的年龄通常通过对象经历的垃圾回收次数来计算。当一个对象经历了一次垃圾回收后仍然存活,它的年龄就会加 1。
  • JVM 通常会将新生代内存分为多个区域,其中包括 Eden 区和两个 Survivor 区。在应用程序运行过程中,新创建>- 的对象首先被分配到 Eden 区。当 Eden 区满时,JVM 会对其中的对象进行垃圾回收,并将仍然存活的对象移动到 Survivor 0 区。如果 Survivor 0 区也满了,那么垃圾回收器会再次对其中的对象进行垃圾回收,并将仍然存活的对象移动到 Survivor 1 区。在下一次垃圾回收时,存活时间较长的对象会被移动到老年代中。
  • 在 JVM 进行垃圾回收时,可以通过打印对象年龄分布情况来了解每个年龄段中存活对象的数量。这对于调整垃圾回收策略、优化内存使用等方面非常有帮助。通常情况下,可以通过 -XX:+PrintTenuringDistribution 参数来打印对象年龄分布情况。

堆内存的划分

  • 在 Java 中,堆内存(Heap Memory)通常被划分为新生代(Young Generation)、老年代(Old Generation)和永久代(Permanent Generation,JDK 8 及之前版本中使用)或元空间(Metaspace,JDK 9 及之后版本中使用)等多个部分。
  • 新生代是用于存放新创建的对象的一块内存区域,通常包括 Eden 区、Survivor 0 区和 Survivor 1 区三个部分。当程序创建一个新对象时,它会被分配到 Eden 区。当 Eden 区满时,Java 垃圾回收器会对其中的对象进行垃圾回收,并将仍然存活的对象移动到 Survivor 0 区。如果 Survivor 0 区也满了,那么垃圾回收器会再次对其中的对象进行垃圾回收,并将仍然存活的对象移动到 Survivor 1 区。在下一次垃圾回收时,存活时间较长的对象会被移动到老年代中。
  • 老年代是用于存储长生命周期的对象的一块内存区域。当对象在新生代内存中经历多次垃圾回收后仍然存活,它就会被移动到老年代中。由于老年代中的对象通常具有较长的生命周期,因此对应用程序的暂停时间影响较大,需要采用一些高效的垃圾回收算法来处理。
  • 永久代(或元空间)是 JDK 8 及之前版本中使用的一种内存区域,用于存储类和元数据。在永久代(或元空间)中,存储的类和元数据通常具有固定的大小,并且很少进行垃圾回收。在 JDK 9 及之后版本中,永久代已被完全移除,元空间成为了 Java 类和元数据的唯一存储区域。
  • 总的来说,Java 堆内存的划分可以根据对象的生命周期和类型等因素进行不同的划分,以便更好地管理内存和提高应用程序的性能。

堆转储文件

  • 堆转储文件(Heap Dump File)是指在 Java 应用程序运行过程中,将堆内存中的所有对象信息和状态保存到磁盘上的一个二进制文件。堆转储文件可以用于分析应用程序的内存使用情况、检查内存泄漏等问题。
  • 通过分析堆转储文件,可以了解到当前 Java 应用程序中所有对象的类型、数量、大小、引用关系等信息。这对于诊断内存相关的问题非常有帮助。通常情况下,可以使用一些工具来分析堆转储文件,如 Eclipse Memory Analyzer(MAT)、VisualVM 等。
  • 生成堆转储文件的方法有多种,可以通过命令行参数、JMX 接口、Java 代码等方式进行。例如,在使用 HotSpot JVM 运行 Java 应用程序时,可以使用 -XX:+HeapDumpOnOutOfMemoryError 参数,当发生 OutOfMemoryError 错误时,会自动将堆转储文件保存到当前目录下。
  • 需要注意的是,由于堆转储文件可能包含敏感信息,如密码、密钥等,因此在保存和处理堆转储文件时需要谨慎处理,以确保数据的安全性和保密性。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容