feat:移除了弹窗,服务器添加sls
This commit is contained in:
160
apps/app-frontend/src/helpers/gc/strategies.ts
Normal file
160
apps/app-frontend/src/helpers/gc/strategies.ts
Normal file
@ -0,0 +1,160 @@
|
||||
import type { GcContext, GcStrategyDefinition, GcStrategyId, ResolvedGcStrategyId } from './types'
|
||||
|
||||
// Official Minecraft launcher G1GC tuning. `-XX:SurvivorRatio=8` (the flag in
|
||||
// the leak of the original list was misspelled "SurvialRation", which JVMs
|
||||
// would reject).
|
||||
function buildG1gcMojangArgs(): string {
|
||||
return [
|
||||
'-XX:+UseG1GC',
|
||||
'-XX:+ParallelRefProcEnabled',
|
||||
'-XX:MaxGCPauseMillis=200',
|
||||
'-XX:+UnlockExperimentalVMOptions',
|
||||
'-XX:+DisableExplicitGC',
|
||||
'-XX:+AlwaysPreTouch',
|
||||
'-XX:G1NewSizePercent=30',
|
||||
'-XX:G1MaxNewSizePercent=40',
|
||||
'-XX:G1HeapRegionSize=8M',
|
||||
'-XX:G1ReservePercent=15',
|
||||
'-XX:G1HeapWastePercent=5',
|
||||
'-XX:G1MixedGCCountTarget=4',
|
||||
'-XX:InitiatingHeapOccupancyPercent=15',
|
||||
'-XX:G1MixedGCLiveThresholdPercent=90',
|
||||
'-XX:G1RSetUpdatingPauseTimePercent=5',
|
||||
'-XX:SurvivorRatio=8',
|
||||
].join(' ')
|
||||
}
|
||||
|
||||
// PCL-style Shenandoah (adaptive, no large pages — the safe default variant).
|
||||
function buildPclShenandoahArgs(): string {
|
||||
return [
|
||||
'-XX:+UseShenandoahGC',
|
||||
'-XX:ShenandoahGCHeuristics=adaptive',
|
||||
'-XX:+AlwaysPreTouch',
|
||||
'-XX:+DisableExplicitGC',
|
||||
].join(' ')
|
||||
}
|
||||
|
||||
// Shenandoah with large pages enabled (may warn on systems without support).
|
||||
function buildShenandoahArgs(): string {
|
||||
return [
|
||||
'-XX:+UseShenandoahGC',
|
||||
'-XX:ShenandoahGCHeuristics=adaptive',
|
||||
'-XX:+AlwaysPreTouch',
|
||||
'-XX:+UseLargePages',
|
||||
'-XX:+DisableExplicitGC',
|
||||
].join(' ')
|
||||
}
|
||||
|
||||
function buildZgcArgs(javaMajorVersion: number | null): string {
|
||||
const args = ['-XX:+UseZGC']
|
||||
// Generational ZGC only exists on JDK 21+.
|
||||
if (javaMajorVersion !== null && javaMajorVersion >= 21) {
|
||||
args.push('-XX:+ZGenerational')
|
||||
}
|
||||
args.push('-XX:+AlwaysPreTouch', '-XX:-ZUncommit')
|
||||
return args.join(' ')
|
||||
}
|
||||
|
||||
// Detection only tags a preset when its *complete* flag set is present in the
|
||||
// pasted args — a partial or edited arg list is treated as the user's own raw
|
||||
// args, never auto-mislabeled as a preset.
|
||||
function tokensOf(argString: string): string[] {
|
||||
return argString.split(/\s+/).filter(Boolean)
|
||||
}
|
||||
|
||||
function hasFullArgSet(pastedArgs: string, presetArgString: string): boolean {
|
||||
const inputSet = new Set(tokensOf(pastedArgs))
|
||||
return tokensOf(presetArgString).every((token) => inputSet.has(token))
|
||||
}
|
||||
|
||||
function detectG1gcMojang(args: string): boolean {
|
||||
return hasFullArgSet(args, buildG1gcMojangArgs())
|
||||
}
|
||||
|
||||
// PCL Shenandoah: complete adaptive set, and no large pages.
|
||||
function detectPclShenandoah(args: string): boolean {
|
||||
return hasFullArgSet(args, buildPclShenandoahArgs()) && !args.includes('-XX:+UseLargePages')
|
||||
}
|
||||
|
||||
// Shenandoah with large pages (its full set already requires `-XX:+UseLargePages`).
|
||||
function detectShenandoah(args: string): boolean {
|
||||
return hasFullArgSet(args, buildShenandoahArgs())
|
||||
}
|
||||
|
||||
function detectZgc(args: string): boolean {
|
||||
return hasFullArgSet(args, buildZgcArgs(null))
|
||||
}
|
||||
|
||||
export const GC_STRATEGY_DEFINITIONS: Record<ResolvedGcStrategyId, GcStrategyDefinition> = {
|
||||
'g1gc-mojang': {
|
||||
id: 'g1gc-mojang',
|
||||
baseArgs: buildG1gcMojangArgs(),
|
||||
detect: detectG1gcMojang,
|
||||
buildArgs: () => buildG1gcMojangArgs(),
|
||||
},
|
||||
pcl: {
|
||||
id: 'pcl',
|
||||
baseArgs: buildPclShenandoahArgs(),
|
||||
detect: detectPclShenandoah,
|
||||
buildArgs: () => buildPclShenandoahArgs(),
|
||||
},
|
||||
shenandoah: {
|
||||
id: 'shenandoah',
|
||||
baseArgs: buildShenandoahArgs(),
|
||||
detect: detectShenandoah,
|
||||
buildArgs: () => buildShenandoahArgs(),
|
||||
},
|
||||
zgc: {
|
||||
id: 'zgc',
|
||||
baseArgs: buildZgcArgs(null),
|
||||
detect: detectZgc,
|
||||
buildArgs: (context) => buildZgcArgs(context?.javaMajorVersion ?? null),
|
||||
},
|
||||
}
|
||||
|
||||
export function detectGcStrategy(args: string): ResolvedGcStrategyId | null {
|
||||
for (const [strategyId, definition] of Object.entries(GC_STRATEGY_DEFINITIONS)) {
|
||||
if (definition.detect(args)) {
|
||||
return strategyId as ResolvedGcStrategyId
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function getStrategyBaseArgs(strategyId: GcStrategyId): string {
|
||||
if (strategyId === 'auto') {
|
||||
return GC_STRATEGY_DEFINITIONS['g1gc-mojang'].baseArgs
|
||||
}
|
||||
return GC_STRATEGY_DEFINITIONS[strategyId].baseArgs
|
||||
}
|
||||
|
||||
/**
|
||||
* The preferred strategy plus the fallback chain, ordered by preference. The
|
||||
* backend verifies each block against the actual JVM and picks the first one
|
||||
* that is accepted (pruning unsupported tuning flags along the way).
|
||||
*
|
||||
* Fallbacks only ever move to less resource-hungry strategies — if the
|
||||
* heuristic deliberately avoided ZGC (insufficient resources), we must not
|
||||
* silently jump back up to it when Shenandoah is unavailable.
|
||||
*/
|
||||
const SAFE_TO_DEMANDING: ResolvedGcStrategyId[] = ['g1gc-mojang', 'pcl', 'shenandoah', 'zgc']
|
||||
|
||||
export function buildGcCandidateChain(
|
||||
context: GcContext,
|
||||
preferred: ResolvedGcStrategyId,
|
||||
): { ids: string[]; args: string[][] } {
|
||||
const preferredDemand = SAFE_TO_DEMANDING.indexOf(preferred)
|
||||
const ids: string[] = [preferred]
|
||||
if (preferredDemand > 0) {
|
||||
for (let demand = preferredDemand - 1; demand >= 0; demand -= 1) {
|
||||
ids.push(SAFE_TO_DEMANDING[demand])
|
||||
}
|
||||
}
|
||||
// Absolute last resort: just the G1 selector (known to every HotSpot JVM).
|
||||
ids.push('minimal-g1')
|
||||
const args = ids.map((id) => {
|
||||
if (id === 'minimal-g1') return ['-XX:+UseG1GC']
|
||||
return GC_STRATEGY_DEFINITIONS[id].buildArgs(context).split(/\s+/).filter(Boolean)
|
||||
})
|
||||
return { ids, args }
|
||||
}
|
||||
Reference in New Issue
Block a user