jvm设置参数
-Xmx512m -XX:MaxMetaspaceSize=256m
设置方法
-Xmx512m
含义
-Xmx
是一个 JVM 的标准参数,用于设置 JVM 堆内存的最大可用空间。512m
表示将堆内存的最大值设置为 512 兆字节(MB)。这里的 m
是单位后缀,代表兆字节,也可以使用 M
,大小写不影响其含义。
作用
堆内存是 JVM 中用于存储对象实例的区域,Java 程序中创建的大部分对象都存放在堆中。通过 -Xmx
参数限制堆内存的最大值,可以防止程序无限制地使用系统内存,避免因内存耗尽导致系统崩溃。例如,当运行一个内存消耗较大的 Java 程序时,如果不限制堆内存大小,程序可能会不断申请内存,最终导致系统出现内存不足的情况。设置 -Xmx512m
后,当堆内存使用达到 512MB 时,JVM 会尝试进行垃圾回收以释放内存,如果仍然无法满足内存需求,会抛出 OutOfMemoryError
异常。
-XX:MaxMetaspaceSize=256m
含义
-XX:MaxMetaspaceSize
是一个非标准的 JVM 参数,用于设置元空间(Metaspace)的最大可用空间。元空间是 Java 8 及以后版本中取代永久代(PermGen)的内存区域,主要用于存储类的元数据信息,如类的结构、方法、字段等。256m
表示将元空间的最大值设置为 256 兆字节(MB)。
作用
在 Java 8 之前,类的元数据信息存储在永久代中,永久代有固定的大小限制,容易出现 java.lang.OutOfMemoryError: PermGen space
异常。Java 8 引入了元空间,元空间使用的是本地内存,默认情况下,元空间的大小仅受限于系统的可用内存。但在某些情况下,我们可能需要限制元空间的大小,以防止程序过度使用系统内存。设置 -XX:MaxMetaspaceSize=256m
后,当元空间使用达到 256MB 时,JVM 会尝试清理不再使用的类元数据,如果仍然无法满足内存需求,会抛出 java.lang.OutOfMemoryError: Metaspace
异常。
四种引用类型
强引用
强引用是最常见的引用类型。只要强引用存在,垃圾回收器就不会回收被引用的对象。
软引用
软引用(Soft Reference)在 Java 里是一种比较特殊的引用类型,当内存足够时,软引用所指向的对象不会被垃圾回收;而当内存不足时,垃圾回收器会回收这些对象。软引用常被用于实现缓存机制,比如图片缓存、数据缓存等,下面为你详细介绍软引用的使用实例。
弱引用
弱引用所引用的对象只要发生垃圾回收,就会被回收,无论内存是否充足。
虚引用
虚引用主要用于跟踪对象被垃圾回收的状态,它必须和引用队列(ReferenceQueue
)联合使用。虚引用的 get()
方法总是返回 null
,当虚引用所引用的对象被垃圾回收时,会将该虚引用添加到引用队列中。
package org.example;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
public class ReferenceExample {
public static void main(String[] args) {
// 创建一个强引用对象
Object strongRef = new Object();
System.out.println("Before GC: " + strongRef);
// 手动触发垃圾回收
System.gc();
System.out.println("After GC: " + strongRef);
// 解除强引用
strongRef = null;
// 再次手动触发垃圾回收
System.gc();
// 创建一个大对象
byte[] largeObject = new byte[1024 * 1024];
// 创建软引用
SoftReference<byte[]> softRef = new SoftReference<>(largeObject);
// 解除强引用
largeObject = null;
// 尝试触发垃圾回收,通常内存足够时不会回收软引用对象
System.gc();
System.out.println("Soft reference object after first GC: " + softRef.get());
try {
// 模拟内存不足,创建大量对象
byte[] anotherLargeObject1 = new byte[1024 * 1024 * 512];
} catch (OutOfMemoryError e) {
System.out.println("Out of memory error occurred.");
}
System.out.println("Soft reference object after potential memory shortage: " + softRef.get());
// 创建一个对象
Object weakObject = new Object();
// 创建弱引用
WeakReference<Object> weakRef = new WeakReference<>(weakObject);
// 解除强引用
weakObject = null;
System.out.println("Weak reference object before GC: " + weakRef.get());
// 手动触发垃圾回收
System.gc();
System.out.println("Weak reference object after GC: " + weakRef.get());
// 创建引用队列
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
// 创建对象
Object phantomObject = new Object();
// 创建虚引用
PhantomReference<Object> phantomRef = new PhantomReference<>(phantomObject, referenceQueue);
System.out.println("Phantom reference object: " + phantomRef.get());
// 解除强引用
phantomObject = null;
// 手动触发垃圾回收
System.gc();
try {
// 等待虚引用被加入引用队列
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 检查引用队列中是否有虚引用
if (referenceQueue.poll() != null) {
System.out.println("Phantom reference has been enqueued.");
}
}
}
查看所有Java进程pid
查看指定进程的垃圾回收情况
S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
参考文章【JVM】jstat命令详解---JVM的统计监测工具 - Angel挤一挤 - 博客园
基于对象年龄(默认情况)
在 Java 的分代垃圾回收模型里,新生代又分为 Eden 区和两个 Survivor 区(通常命名为 Survivor0 和 Survivor1)。新创建的对象一般会优先分配到 Eden 区。当 Eden 区空间不足时,会触发 Minor GC(新生代垃圾回收)。
在每次 Minor GC 时,如果对象没有被回收,就会被移动到 Survivor 区,并且对象的年龄会加 1。默认情况下,当对象的年龄达到 15 时,就会被晋升到老年代。所以,如果对象每次在 Minor GC 时都存活下来,那么它需要经历 15 次 Minor GC 才会进入老年代。
你可以通过 -XX:MaxTenuringThreshold
参数来调整这个阈值,例如 -XX:MaxTenuringThreshold=5
表示对象年龄达到 5 时就会进入老年代。
大对象直接进入老年代
如果创建的对象是大对象(对象大小超过 -XX:PretenureSizeThreshold
参数设置的值),那么这个对象不会经过新生代,而是直接被分配到老年代。这种情况下,对象不需要经历任何 GC 就会进入老年代。
动态对象年龄判定
为了更好地适应不同程序的内存使用情况,JVM 还提供了动态对象年龄判定机制。当 Survivor 区中相同年龄所有对象大小的总和大于 Survivor 区空间的一半时,年龄大于或等于该年龄的对象就可以直接进入老年代,而不需要等到达到最大年龄阈值。在这种情况下,对象进入老年代所需的 GC 次数会小于最大年龄阈值对应的 GC 次数。
增加 -XX:+PrintGCDetails 打印GC日志
[0.004s][warning][gc] -XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.
[0.015s][info ][gc,init] CardTable entry size: 512
[0.015s][info ][gc ] Using G1
[0.017s][info ][gc,init] Version: 18.0.2+9-FR (release)
[0.017s][info ][gc,init] CPUs: 16 total, 16 available
[0.017s][info ][gc,init] Memory: 15706M
[0.017s][info ][gc,init] Large Page Support: Disabled
[0.017s][info ][gc,init] NUMA Support: Disabled
[0.017s][info ][gc,init] Compressed Oops: Enabled (32-bit)
[0.017s][info ][gc,init] Heap Region Size: 1M
[0.017s][info ][gc,init] Heap Min Capacity: 8M
[0.017s][info ][gc,init] Heap Initial Capacity: 246M
[0.017s][info ][gc,init] Heap Max Capacity: 512M
[0.017s][info ][gc,init] Pre-touch: Disabled
[0.017s][info ][gc,init] Parallel Workers: 13
[0.017s][info ][gc,init] Concurrent Workers: 3
[0.017s][info ][gc,init] Concurrent Refinement Workers: 13
[0.017s][info ][gc,init] Periodic GC: Disabled
[0.018s][info ][gc,metaspace] CDS archive(s) mapped at: [0x0000000800000000-0x0000000800ba0000-0x0000000800ba0000), size 12189696, SharedBaseAddress: 0x0000000800000000, ArchiveRelocationMode: 0.
[0.018s][info ][gc,metaspace] Compressed class space mapped at: 0x0000000800c00000-0x000000080dc00000, reserved size: 218103808
[0.018s][info ][gc,metaspace] Narrow klass base: 0x0000000800000000, Narrow klass shift: 0, Narrow klass range: 0x100000000
Created object 0
Created object 1
Created object 2
Created object 3
Created object 4
[0.203s][info ][gc,start ] GC(0) Pause Young (Concurrent Start) (G1 Humongous Allocation)
[0.204s][info ][gc,task ] GC(0) Using 5 workers of 13 for evacuation
[0.206s][info ][gc,phases ] GC(0) Pre Evacuate Collection Set: 0.4ms
[0.206s][info ][gc,phases ] GC(0) Merge Heap Roots: 0.1ms
[0.206s][info ][gc,phases ] GC(0) Evacuate Collection Set: 1.3ms
[0.206s][info ][gc,phases ] GC(0) Post Evacuate Collection Set: 0.2ms
[0.206s][info ][gc,phases ] GC(0) Other: 0.5ms
[0.206s][info ][gc,heap ] GC(0) Eden regions: 5->0(17)
[0.206s][info ][gc,heap ] GC(0) Survivor regions: 0->2(3)
[0.206s][info ][gc,heap ] GC(0) Old regions: 0->0
[0.206s][info ][gc,heap ] GC(0) Archive regions: 0->0
[0.206s][info ][gc,heap ] GC(0) Humongous regions: 105->105
[0.206s][info ][gc,metaspace] GC(0) Metaspace: 842K(960K)->842K(960K) NonClass: 779K(832K)->779K(832K) Class: 62K(128K)->62K(128K)
[0.206s][info ][gc ] GC(0) Pause Young (Concurrent Start) (G1 Humongous Allocation) 109M->106M(246M) 2.907ms
[0.206s][info ][gc ] GC(1) Concurrent Undo Cycle
[0.206s][info ][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.00s
[0.206s][info ][gc,marking ] GC(1) Concurrent Cleanup for Next Mark
[0.206s][info ][gc,marking ] GC(1) Concurrent Cleanup for Next Mark 0.032ms
[0.206s][info ][gc ] GC(1) Concurrent Undo Cycle 0.106ms
Created object 5
[0.215s][info ][gc,start ] GC(2) Pause Young (Concurrent Start) (G1 Humongous Allocation)
[0.215s][info ][gc,task ] GC(2) Using 5 workers of 13 for evacuation
[0.217s][info ][gc,phases ] GC(2) Pre Evacuate Collection Set: 0.2ms
[0.217s][info ][gc,phases ] GC(2) Merge Heap Roots: 0.0ms
[0.217s][info ][gc,phases ] GC(2) Evacuate Collection Set: 0.9ms
[0.217s][info ][gc,phases ] GC(2) Post Evacuate Collection Set: 0.2ms
[0.217s][info ][gc,phases ] GC(2) Other: 0.1ms
[0.217s][info ][gc,heap ] GC(2) Eden regions: 1->0(39)
[0.217s][info ][gc,heap ] GC(2) Survivor regions: 2->2(3)
[0.217s][info ][gc,heap ] GC(2) Old regions: 0->0
[0.217s][info ][gc,heap ] GC(2) Archive regions: 0->0
[0.217s][info ][gc,heap ] GC(2) Humongous regions: 126->126
[0.217s][info ][gc,metaspace] GC(2) Metaspace: 842K(960K)->842K(960K) NonClass: 779K(832K)->779K(832K) Class: 62K(128K)->62K(128K)
[0.217s][info ][gc ] GC(2) Pause Young (Concurrent Start) (G1 Humongous Allocation) 127M->127M(246M) 1.747ms
[0.217s][info ][gc ] GC(3) Concurrent Mark Cycle
[0.217s][info ][gc,cpu ] GC(2) User=0.00s Sys=0.00s Real=0.00s
[0.217s][info ][gc,marking ] GC(3) Concurrent Clear Claimed Marks
[0.217s][info ][gc,marking ] GC(3) Concurrent Clear Claimed Marks 0.009ms
[0.217s][info ][gc,marking ] GC(3) Concurrent Scan Root Regions
[0.218s][info ][gc,marking ] GC(3) Concurrent Scan Root Regions 0.757ms
[0.218s][info ][gc,marking ] GC(3) Concurrent Mark
[0.218s][info ][gc,marking ] GC(3) Concurrent Mark From Roots
[0.218s][info ][gc,task ] GC(3) Using 3 workers of 3 for marking
[0.218s][info ][gc,marking ] GC(3) Concurrent Mark From Roots 0.422ms
[0.218s][info ][gc,marking ] GC(3) Concurrent Preclean
[0.218s][info ][gc,marking ] GC(3) Concurrent Preclean 0.008ms
[0.229s][info ][gc,start ] GC(3) Pause Remark
[0.229s][info ][gc ] GC(3) Pause Remark 148M->148M(249M) 0.589ms
[0.229s][info ][gc,cpu ] GC(3) User=0.00s Sys=0.00s Real=0.00s
[0.229s][info ][gc,marking ] GC(3) Concurrent Mark 11.727ms
[0.229s][info ][gc,marking ] GC(3) Concurrent Rebuild Remembered Sets
[0.229s][info ][gc,marking ] GC(3) Concurrent Rebuild Remembered Sets 0.004ms
[0.229s][info ][gc,start ] GC(3) Pause Cleanup
[0.229s][info ][gc ] GC(3) Pause Cleanup 148M->148M(249M) 0.011ms
[0.229s][info ][gc,cpu ] GC(3) User=0.00s Sys=0.00s Real=0.00s
[0.229s][info ][gc,marking ] GC(3) Concurrent Cleanup for Next Mark
Created object 6
[0.230s][info ][gc,marking ] GC(3) Concurrent Cleanup for Next Mark 0.882ms
[0.230s][info ][gc ] GC(3) Concurrent Mark Cycle 13.619ms
Created object 7
[0.239s][info ][gc,start ] GC(4) Pause Young (Concurrent Start) (G1 Humongous Allocation)
[0.239s][info ][gc,task ] GC(4) Using 5 workers of 13 for evacuation
[0.241s][info ][gc,phases ] GC(4) Pre Evacuate Collection Set: 0.2ms
[0.241s][info ][gc,phases ] GC(4) Merge Heap Roots: 0.0ms
[0.241s][info ][gc,phases ] GC(4) Evacuate Collection Set: 1.1ms
[0.241s][info ][gc,phases ] GC(4) Post Evacuate Collection Set: 0.2ms
[0.241s][info ][gc,phases ] GC(4) Other: 0.1ms
[0.241s][info ][gc,heap ] GC(4) Eden regions: 1->0(30)
[0.241s][info ][gc,heap ] GC(4) Survivor regions: 2->2(6)
[0.241s][info ][gc,heap ] GC(4) Old regions: 0->0
[0.241s][info ][gc,heap ] GC(4) Archive regions: 0->0
[0.241s][info ][gc,heap ] GC(4) Humongous regions: 168->168
[0.241s][info ][gc,metaspace] GC(4) Metaspace: 842K(960K)->842K(960K) NonClass: 779K(832K)->779K(832K) Class: 62K(128K)->62K(128K)
[0.241s][info ][gc ] GC(4) Pause Young (Concurrent Start) (G1 Humongous Allocation) 169M->169M(249M) 1.799ms
[0.241s][info ][gc ] GC(5) Concurrent Mark Cycle
[0.241s][info ][gc,cpu ] GC(4) User=0.00s Sys=0.00s Real=0.00s
[0.241s][info ][gc,marking ] GC(5) Concurrent Clear Claimed Marks
[0.241s][info ][gc,marking ] GC(5) Concurrent Clear Claimed Marks 0.013ms
[0.241s][info ][gc,marking ] GC(5) Concurrent Scan Root Regions
[0.242s][info ][gc,marking ] GC(5) Concurrent Scan Root Regions 0.578ms
[0.242s][info ][gc,marking ] GC(5) Concurrent Mark
[0.242s][info ][gc,marking ] GC(5) Concurrent Mark From Roots
[0.242s][info ][gc,task ] GC(5) Using 3 workers of 3 for marking
[0.242s][info ][gc,marking ] GC(5) Concurrent Mark From Roots 0.122ms
[0.242s][info ][gc,marking ] GC(5) Concurrent Preclean
[0.242s][info ][gc,marking ] GC(5) Concurrent Preclean 0.011ms
[0.259s][info ][gc,start ] GC(5) Pause Remark
[0.259s][info ][gc ] GC(5) Pause Remark 190M->190M(319M) 0.818ms
[0.259s][info ][gc,cpu ] GC(5) User=0.00s Sys=0.00s Real=0.00s
[0.260s][info ][gc,marking ] GC(5) Concurrent Mark 17.853ms
[0.260s][info ][gc,marking ] GC(5) Concurrent Rebuild Remembered Sets
[0.260s][info ][gc,marking ] GC(5) Concurrent Rebuild Remembered Sets 0.004ms
[0.260s][info ][gc,start ] GC(5) Pause Cleanup
[0.260s][info ][gc ] GC(5) Pause Cleanup 190M->190M(319M) 0.011ms
[0.260s][info ][gc,cpu ] GC(5) User=0.00s Sys=0.00s Real=0.00s
[0.260s][info ][gc,marking ] GC(5) Concurrent Cleanup for Next Mark
Created object 8
[0.261s][info ][gc,marking ] GC(5) Concurrent Cleanup for Next Mark 1.038ms
[0.261s][info ][gc ] GC(5) Concurrent Mark Cycle 19.612ms
Created object 9
GC 日志分析
初始信息
[0.004s][warning][gc] -XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.
[0.015s][info ][gc,init] CardTable entry size: 512
[0.015s][info ][gc ] Using G1
[0.017s][info ][gc,init] Version: 18.0.2+9-FR (release)
...
- 首先给出警告,提示
-XX:+PrintGCDetails
已被弃用。 - 表明使用的垃圾回收器是 G1(Garbage - First)。
- 还展示了 JVM 的版本、CPU 数量、内存大小、堆区域大小等初始化信息。
垃圾回收信息
以第一次 GC 日志为例:
[0.203s][info ][gc,start ] GC(0) Pause Young (Concurrent Start) (G1 Humongous Allocation)
[0.204s][info ][gc,task ] GC(0) Using 5 workers of 13 for evacuation
...
[0.206s][info ][gc,heap ] GC(0) Eden regions: 5->0(17)
[0.206s][info ][gc,heap ] GC(0) Survivor regions: 0->2(3)
[0.206s][info ][gc,heap ] GC(0) Old regions: 0->0
[0.206s][info ][gc,heap ] GC(0) Archive regions: 0->0
[0.206s][info ][gc,heap ] GC(0) Humongous regions: 105->105
[0.206s][info ][gc,metaspace] GC(0) Metaspace: 842K(960K)->842K(960K) NonClass: 779K(832K)->779K(832K) Class: 62K(128K)->62K(128K)
[0.206s][info ][gc ] GC(0) Pause Young (Concurrent Start) (G1 Humongous Allocation) 109M->106M(246M) 2.907ms
- GC 触发原因:
GC(0) Pause Young (Concurrent Start) (G1 Humongous Allocation)
说明这是一次新生代垃圾回收(Young GC),触发原因是大对象分配(G1 Humongous Allocation)。 - 工作线程:使用 5 个工作线程进行对象疏散(evacuation)操作。
- 堆区域变化:
Eden regions: 5->0(17)
:Eden 区从使用 5 个区域变为 0 个区域,总共有 17 个区域。Survivor regions: 0->2(3)
:Survivor 区从 0 个使用区域变为 2 个使用区域,总共有 3 个区域。Old regions: 0->0
:老年代区域使用情况无变化。Humongous regions: 105->105
:大对象区域使用情况无变化。
- 元空间变化:元空间大小在 GC 前后保持不变。
- 整体堆变化:堆内存从 109MB 变为 106MB,堆总容量为 246MB,本次 GC 耗时 2.907ms。
后续的 GC 日志也类似,反映了程序运行过程中不断进行新生代垃圾回收,并且在某些时候会触发并发标记周期(Concurrent Mark Cycle)来对堆进行更全面的标记和清理。