11import * as fs from "fs-extra" ;
2- import { commands , ExtensionContext , window , workspace } from "vscode" ;
2+ import { commands , ConfigurationTarget , ExtensionContext , window , workspace } from "vscode" ;
33import { CloseAction , ErrorAction , ErrorHandler , Message } from "vscode-languageclient" ;
44import { ClientCommandConstants } from "../commands/commandConstants" ;
55import { HEAP_DUMP_LOCATION } from "../server/java/jvmArguments" ;
66import { Telemetry } from "../telemetry" ;
77import 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 */
7879async 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
9397const 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}
0 commit comments