Compare commits

..

No commits in common. "a892c1ad8ff313de33500a2aeb88df75b23f91eb" and "4b624693ecaa7b8c97c3c3ed42f6829953f6b7ce" have entirely different histories.

4 changed files with 7 additions and 20 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "real-debrid-downloader", "name": "real-debrid-downloader",
"version": "1.7.94", "version": "1.7.93",
"description": "Desktop downloader", "description": "Desktop downloader",
"main": "build/main/main/main.js", "main": "build/main/main/main.js",
"author": "Sucukdeluxe", "author": "Sucukdeluxe",

View File

@ -1409,10 +1409,7 @@ export class DownloadManager extends EventEmitter {
this.appSessionStartedAt = startedAt; this.appSessionStartedAt = startedAt;
this.runtimePersistedTotalMs = Math.max(0, Number(settings.totalRuntimeAllTimeMs || 0)); this.runtimePersistedTotalMs = Math.max(0, Number(settings.totalRuntimeAllTimeMs || 0));
this.runtimePersistedAt = startedAt; this.runtimePersistedAt = startedAt;
// loadSession already returns a fresh, standalone object graph — no need to this.session = cloneSession(session);
// deep-clone again. This avoids duplicating the entire session in memory at
// startup which can spike peak heap on low-RAM servers.
this.session = session;
this.itemCount = Object.keys(this.session.items).length; this.itemCount = Object.keys(this.session.items).length;
this.storagePaths = storagePaths; this.storagePaths = storagePaths;
this.debridService = new DebridService(settings, { this.debridService = new DebridService(settings, {

View File

@ -89,14 +89,6 @@ let resolveExtractorCommandInFlight: Promise<string> | null = null;
const EXTRACTOR_RETRY_AFTER_MS = 30_000; const EXTRACTOR_RETRY_AFTER_MS = 30_000;
const DEFAULT_ZIP_ENTRY_MEMORY_LIMIT_MB = 256; const DEFAULT_ZIP_ENTRY_MEMORY_LIMIT_MB = 256;
/** Compute a safe JVM -Xmx value based on available physical RAM.
* Reserves 4 GB for Windows + Electron + other processes, caps at 16 GB. */
function jvmMaxHeapArg(): string {
const totalGb = os.totalmem() / (1024 ** 3);
const heapGb = Math.max(1, Math.min(Math.floor(totalGb - 4), 16));
return `-Xmx${heapGb}g`;
}
const EXTRACTOR_PROBE_TIMEOUT_MS = 8_000; const EXTRACTOR_PROBE_TIMEOUT_MS = 8_000;
const DEFAULT_EXTRACT_CPU_BUDGET_PERCENT = 80; const DEFAULT_EXTRACT_CPU_BUDGET_PERCENT = 80;
let currentExtractCpuPriority: string | undefined; let currentExtractCpuPriority: string | undefined;
@ -1400,7 +1392,7 @@ function startDaemon(layout: JvmExtractorLayout): boolean {
"-Dfile.encoding=UTF-8", "-Dfile.encoding=UTF-8",
`-Djava.io.tmpdir=${jvmTmpDir}`, `-Djava.io.tmpdir=${jvmTmpDir}`,
"-Xms1g", "-Xms1g",
jvmMaxHeapArg(), "-Xmx32g",
"-XX:+UseG1GC", "-XX:+UseG1GC",
"-XX:MaxGCPauseMillis=50", "-XX:MaxGCPauseMillis=50",
"-cp", "-cp",
@ -1648,7 +1640,7 @@ async function runJvmExtractCommand(
"-Dfile.encoding=UTF-8", "-Dfile.encoding=UTF-8",
`-Djava.io.tmpdir=${jvmTmpDir}`, `-Djava.io.tmpdir=${jvmTmpDir}`,
"-Xms1g", "-Xms1g",
jvmMaxHeapArg(), "-Xmx32g",
"-XX:+UseG1GC", "-XX:+UseG1GC",
"-XX:MaxGCPauseMillis=50", "-XX:MaxGCPauseMillis=50",
"-cp", "-cp",

View File

@ -721,14 +721,12 @@ export function normalizeLoadedSessionTransientFields(session: SessionState): Se
function readSessionFile(filePath: string): SessionState | null { function readSessionFile(filePath: string): SessionState | null {
try { try {
// Inline readFileSync into JSON.parse so the raw string is not bound to a const raw = fs.readFileSync(filePath, "utf8");
// variable and can be GC'd immediately — avoids holding the full JSON text const parsed = JSON.parse(raw) as unknown;
// and the parsed object graph in memory simultaneously.
const parsed = JSON.parse(fs.readFileSync(filePath, "utf8")) as unknown;
const session = normalizeLoadedSessionTransientFields(normalizeLoadedSession(parsed)); const session = normalizeLoadedSessionTransientFields(normalizeLoadedSession(parsed));
const pkgCount = Object.keys(session.packages).length; const pkgCount = Object.keys(session.packages).length;
const itemCount = Object.keys(session.items).length; const itemCount = Object.keys(session.items).length;
logger.info(`Session geladen: ${filePath} (${pkgCount} Pakete, ${itemCount} Items)`); logger.info(`Session geladen: ${filePath} (${pkgCount} Pakete, ${itemCount} Items, ${raw.length} Bytes)`);
return session; return session;
} catch (error) { } catch (error) {
logger.error(`Session-Datei nicht lesbar: ${filePath}: ${String(error)}`); logger.error(`Session-Datei nicht lesbar: ${filePath}: ${String(error)}`);