Skip to content

Commit d4828df

Browse files
committed
Add button to double heap size on OOM
Copied from vscode-java. Closes #700 Signed-off-by: David Thompson <davthomp@redhat.com>
1 parent ca4da0d commit d4828df

File tree

5 files changed

+35
-7
lines changed

5 files changed

+35
-7
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,4 +597,4 @@
597597
}
598598
]
599599
}
600-
}
600+
}

src/client/clientErrorHandler.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as fs from "fs-extra";
2-
import { commands, ExtensionContext, window, workspace } from "vscode";
2+
import { commands, ConfigurationTarget, ExtensionContext, window, workspace } from "vscode";
33
import { CloseAction, ErrorAction, ErrorHandler, Message } from "vscode-languageclient";
44
import { ClientCommandConstants } from "../commands/commandConstants";
55
import { HEAP_DUMP_LOCATION } from "../server/java/jvmArguments";
66
import { Telemetry } from "../telemetry";
77
import glob = require("glob");
8+
import { totalmem } from "os";
89

910
/**
1011
* An error handler that restarts the language server,
@@ -77,8 +78,9 @@ export async function cleanUpHeapDumps(context: ExtensionContext): Promise<void>
7778
*/
7879
async function showOOMMessage(): Promise<void> {
7980
const DOCS = 'More info...';
81+
const DOUBLE = 'Double allocated memory';
8082
const result = await window.showErrorMessage('The XML Language Server crashed due to an Out Of Memory Error, and will not be restarted. ', //
81-
DOCS);
83+
DOUBLE, DOCS);
8284
if (result === DOCS) {
8385
Telemetry.sendTelemetry(Telemetry.OPEN_OOM_DOCS_EVT);
8486
await commands.executeCommand(ClientCommandConstants.OPEN_DOCS,
@@ -87,10 +89,13 @@ async function showOOMMessage(): Promise<void> {
8789
section: 'the-language-server-crashes-due-to-an-out-of-memory-error'
8890
}
8991
);
92+
} else if (result === DOUBLE) {
93+
doubleAllocatedMemory();
9094
}
9195
}
9296

9397
const HEAP_DUMP_FOLDER_EXTRACTOR = new RegExp(`${HEAP_DUMP_LOCATION}(?:'([^']+)'|"([^"]+)"|([^\\s]+))`);
98+
const MAX_HEAP_SIZE_EXTRACTOR = new RegExp(`-Xmx([0-9]+)[kKmMgG]`);
9499

95100
/**
96101
* Returns the heap dump folder defined in the user's preferences, or undefined if the user does not set the heap dump folder
@@ -122,4 +127,24 @@ function getXmxFromSettings(): string {
122127
}
123128
}
124129
return 'DEFAULT';
130+
}
131+
132+
/**
133+
* Double the memory allocated to lemminx in the vmargs parameter
134+
*/
135+
async function doubleAllocatedMemory() {
136+
let vmargs: string = workspace.getConfiguration('xml.server').get('vmargs', null);
137+
const results = MAX_HEAP_SIZE_EXTRACTOR.exec(vmargs);
138+
if (results && results[0]) {
139+
const maxMemArg: string = results[0];
140+
const maxMemValue: number = Number(results[1]);
141+
const newMaxMemArg: string = maxMemArg.replace(maxMemValue.toString(), (maxMemValue * 2).toString());
142+
vmargs = vmargs.replace(maxMemArg, newMaxMemArg);
143+
await workspace.getConfiguration().update("xml.server.vmargs", vmargs, ConfigurationTarget.Global);
144+
} else {
145+
// by default, many JVM take 1/4 of the physical memory as -Xmx
146+
// in the case it crashes, set -Xmx to half of total physical memory, in megabytes
147+
vmargs = `-Xmx ${Math.trunc(totalmem()/2/1000000)}m ${vmargs}`;
148+
await workspace.getConfiguration().update("xml.server.vmargs", vmargs, ConfigurationTarget.Global);
149+
}
125150
}

src/client/xmlClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { TelemetryEvent } from '@redhat-developer/vscode-redhat-telemetry/lib';
2-
import { commands, ExtensionContext, extensions, Position, TextDocument, TextEditor, Uri, window, workspace } from 'vscode';
2+
import { commands, ConfigurationChangeEvent, ExtensionContext, extensions, Position, TextDocument, TextEditor, Uri, window, workspace } from 'vscode';
33
import { Command, ConfigurationParams, ConfigurationRequest, DidChangeConfigurationNotification, ExecuteCommandParams, LanguageClientOptions, MessageType, NotificationType, RequestType, RevealOutputChannelOn, TextDocumentPositionParams } from "vscode-languageclient";
44
import { Executable, LanguageClient } from 'vscode-languageclient/node';
55
import { XMLFileAssociation } from '../api/xmlExtensionApi';

src/settings/settings.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ export function subscribeJDKChangeConfiguration() {
5252
if(hasPreferenceChanged(oldXMLConfig, newXMLConfig, "java.home")) { // checks "xml.java.home", not "java.home"
5353
createReloadWindowMessage("`xml.java.home` path has changed. Please restart VS Code.");
5454
}
55+
if (params.affectsConfiguration("xml.server.vmargs")) {
56+
createReloadWindowMessage("Arguments to the JVM have changed. Please reload VS Code to apply this change.");
57+
}
5558
// update to newest version of config
5659
oldXMLConfig = newXMLConfig;
5760
return;

0 commit comments

Comments
 (0)