mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
Added flag for ept size and increased default size (#24859)
This commit is contained in:
@@ -379,15 +379,30 @@ describe('initializeOutputListenersAndFlush', () => {
|
|||||||
describe('getNodeMemoryArgs', () => {
|
describe('getNodeMemoryArgs', () => {
|
||||||
let osTotalMemSpy: MockInstance;
|
let osTotalMemSpy: MockInstance;
|
||||||
let v8GetHeapStatisticsSpy: MockInstance;
|
let v8GetHeapStatisticsSpy: MockInstance;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
let originalConfig: any;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
osTotalMemSpy = vi.spyOn(os, 'totalmem');
|
osTotalMemSpy = vi.spyOn(os, 'totalmem');
|
||||||
v8GetHeapStatisticsSpy = vi.spyOn(v8, 'getHeapStatistics');
|
v8GetHeapStatisticsSpy = vi.spyOn(v8, 'getHeapStatistics');
|
||||||
delete process.env['GEMINI_CLI_NO_RELAUNCH'];
|
delete process.env['GEMINI_CLI_NO_RELAUNCH'];
|
||||||
|
|
||||||
|
originalConfig = process.config;
|
||||||
|
Object.defineProperty(process, 'config', {
|
||||||
|
value: {
|
||||||
|
...originalConfig,
|
||||||
|
variables: { ...originalConfig?.variables, v8_enable_sandbox: 1 },
|
||||||
|
},
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
|
Object.defineProperty(process, 'config', {
|
||||||
|
value: originalConfig,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return empty array if GEMINI_CLI_NO_RELAUNCH is set', () => {
|
it('should return empty array if GEMINI_CLI_NO_RELAUNCH is set', () => {
|
||||||
@@ -400,8 +415,10 @@ describe('getNodeMemoryArgs', () => {
|
|||||||
v8GetHeapStatisticsSpy.mockReturnValue({
|
v8GetHeapStatisticsSpy.mockReturnValue({
|
||||||
heap_size_limit: 8 * 1024 * 1024 * 1024, // 8GB
|
heap_size_limit: 8 * 1024 * 1024 * 1024, // 8GB
|
||||||
});
|
});
|
||||||
// Target is 50% of 16GB = 8GB. Current is 8GB. No relaunch needed.
|
// Target is 50% of 16GB = 8GB. Current is 8GB. Relaunch needed for EPT size only.
|
||||||
expect(getNodeMemoryArgs(false)).toEqual([]);
|
expect(getNodeMemoryArgs(false)).toEqual([
|
||||||
|
'--max-external-pointer-table-size=268435456',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return memory args if current heap limit is insufficient', () => {
|
it('should return memory args if current heap limit is insufficient', () => {
|
||||||
@@ -409,8 +426,11 @@ describe('getNodeMemoryArgs', () => {
|
|||||||
v8GetHeapStatisticsSpy.mockReturnValue({
|
v8GetHeapStatisticsSpy.mockReturnValue({
|
||||||
heap_size_limit: 4 * 1024 * 1024 * 1024, // 4GB
|
heap_size_limit: 4 * 1024 * 1024 * 1024, // 4GB
|
||||||
});
|
});
|
||||||
// Target is 50% of 16GB = 8GB. Current is 4GB. Relaunch needed.
|
// Target is 50% of 16GB = 8GB. Current is 4GB. Relaunch needed for both.
|
||||||
expect(getNodeMemoryArgs(false)).toEqual(['--max-old-space-size=8192']);
|
expect(getNodeMemoryArgs(false)).toEqual([
|
||||||
|
'--max-external-pointer-table-size=268435456',
|
||||||
|
'--max-old-space-size=8192',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log debug info when isDebugMode is true', () => {
|
it('should log debug info when isDebugMode is true', () => {
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ export function validateDnsResolutionOrder(
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_EPT_SIZE = (256 * 1024 * 1024).toString();
|
||||||
|
|
||||||
export function getNodeMemoryArgs(isDebugMode: boolean): string[] {
|
export function getNodeMemoryArgs(isDebugMode: boolean): string[] {
|
||||||
const totalMemoryMB = os.totalmem() / (1024 * 1024);
|
const totalMemoryMB = os.totalmem() / (1024 * 1024);
|
||||||
const heapStats = v8.getHeapStatistics();
|
const heapStats = v8.getHeapStatistics();
|
||||||
@@ -130,16 +132,35 @@ export function getNodeMemoryArgs(isDebugMode: boolean): string[] {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const args: string[] = [];
|
||||||
|
|
||||||
|
// Automatically expand the V8 External Pointer Table to 256MB to prevent
|
||||||
|
// out-of-memory crashes during high native-handle concurrency.
|
||||||
|
// Note: Only supported in specific Node.js versions compiled with V8 Sandbox enabled.
|
||||||
|
const eptFlag = `--max-external-pointer-table-size=${DEFAULT_EPT_SIZE}`;
|
||||||
|
const isV8SandboxEnabled =
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion
|
||||||
|
(process.config?.variables as any)?.v8_enable_sandbox === 1;
|
||||||
|
|
||||||
|
if (
|
||||||
|
isV8SandboxEnabled &&
|
||||||
|
!process.execArgv.some((arg) =>
|
||||||
|
arg.startsWith('--max-external-pointer-table-size'),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
args.push(eptFlag);
|
||||||
|
}
|
||||||
|
|
||||||
if (targetMaxOldSpaceSizeInMB > currentMaxOldSpaceSizeMb) {
|
if (targetMaxOldSpaceSizeInMB > currentMaxOldSpaceSizeMb) {
|
||||||
if (isDebugMode) {
|
if (isDebugMode) {
|
||||||
debugLogger.debug(
|
debugLogger.debug(
|
||||||
`Need to relaunch with more memory: ${targetMaxOldSpaceSizeInMB.toFixed(2)} MB`,
|
`Need to relaunch with more memory: ${targetMaxOldSpaceSizeInMB.toFixed(2)} MB`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return [`--max-old-space-size=${targetMaxOldSpaceSizeInMB}`];
|
args.push(`--max-old-space-size=${targetMaxOldSpaceSizeInMB}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setupUnhandledRejectionHandler() {
|
export function setupUnhandledRejectionHandler() {
|
||||||
|
|||||||
Reference in New Issue
Block a user