feat(api): add method to force garbage collection (#32383)
This commit is contained in:
Родитель
5b28d2a84c
Коммит
f2a974b045
|
@ -256,6 +256,13 @@ class PageHandler {
|
|||
return await this._contentPage.send('disposeObject', options);
|
||||
}
|
||||
|
||||
async ['Heap.collectGarbage']() {
|
||||
Services.obs.notifyObservers(null, "child-gc-request");
|
||||
Cu.forceGC();
|
||||
Services.obs.notifyObservers(null, "child-cc-request");
|
||||
Cu.forceCC();
|
||||
}
|
||||
|
||||
async ['Network.getResponseBody']({requestId}) {
|
||||
return this._pageNetwork.getResponseBody(requestId);
|
||||
}
|
||||
|
|
|
@ -487,6 +487,17 @@ const Browser = {
|
|||
},
|
||||
};
|
||||
|
||||
const Heap = {
|
||||
targets: ['page'],
|
||||
types: {},
|
||||
events: {},
|
||||
methods: {
|
||||
'collectGarbage': {
|
||||
params: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Network = {
|
||||
targets: ['page'],
|
||||
types: networkTypes,
|
||||
|
@ -1002,7 +1013,7 @@ const Accessibility = {
|
|||
}
|
||||
|
||||
this.protocol = {
|
||||
domains: {Browser, Page, Runtime, Network, Accessibility},
|
||||
domains: {Browser, Heap, Page, Runtime, Network, Accessibility},
|
||||
};
|
||||
this.checkScheme = checkScheme;
|
||||
this.EXPORTED_SYMBOLS = ['protocol', 'checkScheme'];
|
||||
|
|
|
@ -2333,6 +2333,11 @@ last redirect. If cannot go forward, returns `null`.
|
|||
|
||||
Navigate to the next page in history.
|
||||
|
||||
## async method: Page.forceGarbageCollection
|
||||
* since: v1.47
|
||||
|
||||
Force the browser to perform garbage collection.
|
||||
|
||||
### option: Page.goForward.waitUntil = %%-navigation-wait-until-%%
|
||||
* since: v1.8
|
||||
|
||||
|
|
|
@ -468,6 +468,10 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
|
|||
return Response.fromNullable((await this._channel.goForward({ ...options, waitUntil })).response);
|
||||
}
|
||||
|
||||
async forceGarbageCollection() {
|
||||
await this._channel.forceGarbageCollection();
|
||||
}
|
||||
|
||||
async emulateMedia(options: { media?: 'screen' | 'print' | null, colorScheme?: 'dark' | 'light' | 'no-preference' | null, reducedMotion?: 'reduce' | 'no-preference' | null, forcedColors?: 'active' | 'none' | null } = {}) {
|
||||
await this._channel.emulateMedia({
|
||||
media: options.media === null ? 'no-override' : options.media,
|
||||
|
|
|
@ -1122,6 +1122,8 @@ scheme.PageGoForwardParams = tObject({
|
|||
scheme.PageGoForwardResult = tObject({
|
||||
response: tOptional(tChannel(['Response'])),
|
||||
});
|
||||
scheme.PageForceGarbageCollectionParams = tOptional(tObject({}));
|
||||
scheme.PageForceGarbageCollectionResult = tOptional(tObject({}));
|
||||
scheme.PageRegisterLocatorHandlerParams = tObject({
|
||||
selector: tString,
|
||||
noWaitAfter: tOptional(tBoolean),
|
||||
|
|
|
@ -323,6 +323,10 @@ export class BidiPage implements PageDelegate {
|
|||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
async forceGarbageCollection(): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
async addInitScript(initScript: InitScript): Promise<void> {
|
||||
const { script } = await this._session.send('script.addPreloadScript', {
|
||||
// TODO: remove function call from the source.
|
||||
|
|
|
@ -247,6 +247,10 @@ export class CRPage implements PageDelegate {
|
|||
return this._go(+1);
|
||||
}
|
||||
|
||||
async forceGarbageCollection(): Promise<void> {
|
||||
await this._mainFrameSession._client.send('HeapProfiler.collectGarbage');
|
||||
}
|
||||
|
||||
async addInitScript(initScript: InitScript, world: types.World = 'main'): Promise<void> {
|
||||
await this._forAllFrameSessions(frame => frame._evaluateOnNewDocument(initScript, world));
|
||||
}
|
||||
|
|
|
@ -137,6 +137,10 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
|
|||
return { response: ResponseDispatcher.fromNullable(this.parentScope(), await this._page.goForward(metadata, params)) };
|
||||
}
|
||||
|
||||
async forceGarbageCollection(params: channels.PageForceGarbageCollectionParams, metadata: CallMetadata): Promise<channels.PageForceGarbageCollectionResult> {
|
||||
await this._page.forceGarbageCollection();
|
||||
}
|
||||
|
||||
async registerLocatorHandler(params: channels.PageRegisterLocatorHandlerParams, metadata: CallMetadata): Promise<channels.PageRegisterLocatorHandlerResult> {
|
||||
const uid = this._page.registerLocatorHandler(params.selector, params.noWaitAfter);
|
||||
return { uid };
|
||||
|
|
|
@ -400,6 +400,10 @@ export class FFPage implements PageDelegate {
|
|||
return success;
|
||||
}
|
||||
|
||||
async forceGarbageCollection(): Promise<void> {
|
||||
await this._session.send('Heap.collectGarbage');
|
||||
}
|
||||
|
||||
async addInitScript(initScript: InitScript, worldName?: string): Promise<void> {
|
||||
this._initScripts.push({ initScript, worldName });
|
||||
await this._session.send('Page.setInitScripts', { scripts: this._initScripts.map(s => ({ script: s.initScript.source, worldName: s.worldName })) });
|
||||
|
|
|
@ -54,6 +54,7 @@ export interface PageDelegate {
|
|||
reload(): Promise<void>;
|
||||
goBack(): Promise<boolean>;
|
||||
goForward(): Promise<boolean>;
|
||||
forceGarbageCollection(): Promise<void>;
|
||||
addInitScript(initScript: InitScript): Promise<void>;
|
||||
removeNonInternalInitScripts(): Promise<void>;
|
||||
closePage(runBeforeUnload: boolean): Promise<void>;
|
||||
|
@ -430,6 +431,10 @@ export class Page extends SdkObject {
|
|||
}), this._timeoutSettings.navigationTimeout(options));
|
||||
}
|
||||
|
||||
forceGarbageCollection(): Promise<void> {
|
||||
return this._delegate.forceGarbageCollection();
|
||||
}
|
||||
|
||||
registerLocatorHandler(selector: string, noWaitAfter: boolean | undefined) {
|
||||
const uid = ++this._lastLocatorHandlerUid;
|
||||
this._locatorHandlers.set(uid, { selector, noWaitAfter });
|
||||
|
|
|
@ -768,6 +768,10 @@ export class WKPage implements PageDelegate {
|
|||
});
|
||||
}
|
||||
|
||||
async forceGarbageCollection(): Promise<void> {
|
||||
await this._session.send('Heap.gc');
|
||||
}
|
||||
|
||||
async addInitScript(initScript: InitScript): Promise<void> {
|
||||
await this._updateBootstrapScript();
|
||||
}
|
||||
|
|
|
@ -2554,6 +2554,11 @@ export interface Page {
|
|||
timeout?: number;
|
||||
}): Promise<void>;
|
||||
|
||||
/**
|
||||
* Force the browser to perform garbage collection.
|
||||
*/
|
||||
forceGarbageCollection(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Returns frame matching the specified criteria. Either `name` or `url` must be specified.
|
||||
*
|
||||
|
|
|
@ -1933,6 +1933,7 @@ export interface PageChannel extends PageEventTarget, EventTargetChannel {
|
|||
exposeBinding(params: PageExposeBindingParams, metadata?: CallMetadata): Promise<PageExposeBindingResult>;
|
||||
goBack(params: PageGoBackParams, metadata?: CallMetadata): Promise<PageGoBackResult>;
|
||||
goForward(params: PageGoForwardParams, metadata?: CallMetadata): Promise<PageGoForwardResult>;
|
||||
forceGarbageCollection(params?: PageForceGarbageCollectionParams, metadata?: CallMetadata): Promise<PageForceGarbageCollectionResult>;
|
||||
registerLocatorHandler(params: PageRegisterLocatorHandlerParams, metadata?: CallMetadata): Promise<PageRegisterLocatorHandlerResult>;
|
||||
resolveLocatorHandlerNoReply(params: PageResolveLocatorHandlerNoReplyParams, metadata?: CallMetadata): Promise<PageResolveLocatorHandlerNoReplyResult>;
|
||||
unregisterLocatorHandler(params: PageUnregisterLocatorHandlerParams, metadata?: CallMetadata): Promise<PageUnregisterLocatorHandlerResult>;
|
||||
|
@ -2070,6 +2071,9 @@ export type PageGoForwardOptions = {
|
|||
export type PageGoForwardResult = {
|
||||
response?: ResponseChannel,
|
||||
};
|
||||
export type PageForceGarbageCollectionParams = {};
|
||||
export type PageForceGarbageCollectionOptions = {};
|
||||
export type PageForceGarbageCollectionResult = void;
|
||||
export type PageRegisterLocatorHandlerParams = {
|
||||
selector: string,
|
||||
noWaitAfter?: boolean,
|
||||
|
|
|
@ -1430,6 +1430,8 @@ Page:
|
|||
slowMo: true
|
||||
snapshot: true
|
||||
|
||||
forceGarbageCollection:
|
||||
|
||||
registerLocatorHandler:
|
||||
parameters:
|
||||
selector: string
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Copyright 2024 Adobe Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { test, expect } from './pageTest';
|
||||
|
||||
test('should work', async ({ page }) => {
|
||||
await page.evaluate(() => {
|
||||
globalThis.objectToDestroy = {};
|
||||
globalThis.weakRef = new WeakRef(globalThis.objectToDestroy);
|
||||
});
|
||||
await page.evaluate(() => globalThis.objectToDestroy = null);
|
||||
await page.forceGarbageCollection();
|
||||
expect(await page.evaluate(() => globalThis.weakRef.deref())).toBe(undefined);
|
||||
});
|
Загрузка…
Ссылка в новой задаче