Skip to content

Commit 3a3a234

Browse files
author
nce40202
committed
feat(jvm-memory-visualizer): 添加大对象直接进入老年代逻辑及配置支持
添加了 `PretenureSizeThreshold` 参数支持,允许配置大对象直接进入老年代的阈值。同时更新了 `LogicTable.vue` 中的逻辑描述,并实现了相关功能。
1 parent d9f6f5e commit 3a3a234

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

src/components/jvm-memory-visualizer/LogicTable.vue

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,26 @@ const logicList = ref<LogicItem[]>([
4848
{
4949
id: 'pretenure_size_threshold',
5050
name: '大对象直入老年代',
51-
desc: '当对象大小超过 Eden 区时,直接在老年代分配(可以通过 -XX:PretenureSizeThreshold 参数配置)',
51+
desc: '当对象大小超过 Eden 区时,直接在老年代分配(可以通过 -XX:PretenureSizeThreshold 参数配置,超过此值的对象直接在老年代分配',
5252
enabled: true,
5353
configurable: false,
54-
implemented: false
54+
implemented: true
55+
},
56+
{
57+
id: 'space_guarantee',
58+
name: '空间分配担保',
59+
desc: '当 Survivor 区空间不足时,会将对象直接分配到老年代',
60+
enabled: true,
61+
configurable: false,
62+
implemented: true
63+
},
64+
{
65+
id: 'max_tenuring_threshold',
66+
name: '对象年龄阈值',
67+
desc: '对象在 Survivor 区中每经过一次 Minor GC 年龄增加 1,当年龄超过阈值时进入老年代(可以通过 -XX:MaxTenuringThreshold 参数配置)',
68+
enabled: true,
69+
configurable: false,
70+
implemented: true
5571
},
5672
{
5773
id: 'dynamic_age_threshold',

src/views/MemoryVisualizer.vue

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ const jvmArgsHelp = [
171171
},
172172
{
173173
"name": "-XX:SurvivorRatio",
174-
"desc": "Eden区与Survivor区的比例",
174+
"desc": "Eden 区与 Survivor 区的比例",
175175
"defaultValue": "8",
176176
"example": "-XX:SurvivorRatio=8"
177177
},
@@ -181,9 +181,15 @@ const jvmArgsHelp = [
181181
"defaultValue": "15",
182182
"example": "-XX:MaxTenuringThreshold=15"
183183
},
184+
{
185+
"name": "-XX:PretenureSizeThreshold",
186+
"desc": "大对象直接进入老年代的阈值",
187+
"defaultValue": "0",
188+
"example": "-XX:PretenureSizeThreshold=1048576"
189+
},
184190
{
185191
"name": "-XX:TargetSurvivorRatio",
186-
"desc": "Survivor区目标使用率",
192+
"desc": "Survivor 区目标使用率",
187193
"defaultValue": "50",
188194
"example": "-XX:TargetSurvivorRatio=50"
189195
}
@@ -237,8 +243,10 @@ const memoryConfig = ref({
237243
survivorRatio: 8, // Eden区和Survivor区的比例,默认为8,表示Eden:Survivor=8:1
238244
maxTenuringThreshold: 15, // 对象晋升年龄阈值,默认为15
239245
targetSurvivorRatio: 50, // Survivor区目标使用率,默认为50%
246+
pretenureSizeThreshold: 0, // 大对象直接进入老年代的阈值,默认为0,表示不启用
240247
});
241248
249+
242250
// JVM参数解析函数
243251
const parseJvmArgs = (args: string) => {
244252
const result = {
@@ -247,7 +255,8 @@ const parseJvmArgs = (args: string) => {
247255
newRatio: 2,
248256
survivorRatio: 8,
249257
maxTenuringThreshold: 15,
250-
targetSurvivorRatio: 50
258+
targetSurvivorRatio: 50,
259+
pretenureSizeThreshold: 0
251260
};
252261
253262
const xmsMatch = args.match(/-Xms(\d+)([kmg])?/i);
@@ -316,6 +325,15 @@ const parseJvmArgs = (args: string) => {
316325
}
317326
}
318327
328+
// 解析PretenureSizeThreshold参数
329+
const pretenureSizeThresholdMatch = args.match(/-XX:PretenureSizeThreshold=(\d+)/i);
330+
if (pretenureSizeThresholdMatch) {
331+
result.pretenureSizeThreshold = parseInt(pretenureSizeThresholdMatch[1]);
332+
if (result.pretenureSizeThreshold < 0) {
333+
throw new Error('PretenureSizeThreshold必须大于等于0');
334+
}
335+
}
336+
319337
// 验证参数
320338
if (result.initialHeap > result.maxHeap) {
321339
throw new Error('初始堆大小不能大于最大堆大小');
@@ -585,7 +603,17 @@ const createObject = () => {
585603
isGarbageCollectable: newObject.value.isGarbageCollectable
586604
} as HeapObject;
587605
588-
if (sizeInBytes > edenSize.value) {
606+
if (sizeInBytes >= memoryConfig.value.pretenureSizeThreshold && memoryConfig.value.pretenureSizeThreshold > 0) {
607+
// 对象大小超过阈值,直接进入Old Gen区
608+
if (getSpaceUsed(MEMORY_SPACE.OLD_GEN) + newObj.size > oldGenSize.value) {
609+
throw applicationError('java.lang.OutOfMemoryError: Java heap space');
610+
}
611+
612+
newObj.space = MEMORY_SPACE.OLD_GEN;
613+
newObj.position = getNextPosition(MEMORY_SPACE.OLD_GEN);
614+
heapObjects.value.push(newObj);
615+
operationLogs.value.unshift(`对象大小(${formatBytes(sizeInBytes)})超过阈值(${formatBytes(memoryConfig.value.pretenureSizeThreshold)}),直接进入老年代`);
616+
} else if (sizeInBytes > edenSize.value) {
589617
// 对象大小超过Eden区大小,尝试直接进入Old Gen区
590618
if (getSpaceUsed(MEMORY_SPACE.OLD_GEN) + newObj.size > oldGenSize.value) {
591619
throw applicationError('java.lang.OutOfMemoryError: Java heap space');

0 commit comments

Comments
 (0)