我需要一些帮助来发现一个小的浏览器/ WebWorker JavaScript中的内存泄漏。我在这段代码中找到了它:
/**
* Resizes an Image
*
* @function scaleImage
* @param {object} oImageBlob blob of image
* @param {int} iHeight New height of Image
* @return {ImageBitmap} ImageBitmap Object
*/
async function scaleImage(oImageBlob, iHeight) {
var img = await self.createImageBitmap(oImageBlob);
var iWidth = Math.round( ( img.width / img.height ) * iHeight);
var canvas = new OffscreenCanvas(iWidth,iHeight);
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
return(canvas.transferToImageBitmap());
}
它的调用来自:
[inside a web worker: Some looping that calls this about 1200 times while parsind files from a s3 bucket ...]
var oImageBlob = await new Response(oS3Object.Body, {}).blob();
var oThumbnail = await scaleImage(oImageBlob, 100);
await IDBputData(oInput.sFileKey, oImageBlob, oInput.sStore, oThumbnail)
[... end of the loop]
另一个内部功能是
/**
* Put information to IndexedDB
*
* @function IDBputData
* @param {string} sKey key of information
* @param {string} sValue information to upload
* @param {string} sStore name of object store
* @param {object} oThumbnail optrional, default: null, thumbnail image
* @return {object} - SUCCESS: array, IndexedDB Identifyer "key"
* - FAIL: Error Message
*/
async function IDBputData(sKey, sValue, sStore, oThumbnail=null) {
var oGeneratedKeys = {};
if(sStore=="panelStore"){
oGeneratedKeys = await getKeyfromSKey(sKey);
}
return new Promise((resolve, reject) => {
const tx = oConn.transaction(sStore, 'readwrite');
const store = tx.objectStore(sStore);
var request = {}
request = store.put({panelkey: oGeneratedKeys.panelkey, layerkey: oGeneratedKeys.layerkey, countrycode: oGeneratedKeys.countrycode, value: sValue, LastModified: new Date(), oThumbnail: oThumbnail});
request.onsuccess = () => (oThumbnail.close(),resolve(request.result));
request.onerror = () => (oThumbnail.close(),reject(request.error));
});
}
当我在Chrome中以这种方式运行它时,它会消耗掉我所有的空闲内存(大约8 GB),然后崩溃(笔记本电脑与CPU/GPU共享内存)。
当我改变
var oThumbnail = await scaleImage(oImageBlob, 100);
至
var oThumbnail = null;
Chrome的RAM消耗保持在800 MB左右,所以必须有一些最上面的函数“scaleImage”。
我试着调整它,但没有成功。
/**
* Resizes an Image
*
* @function scaleImage
* @param {object} oImageBlob blob of image
* @param {int} iHeight New height of Image
* @return {ImageBitmap} ImageBitmap Object
*/
async function scaleImage(oImageBlob, iHeight) {
var img = await self.createImageBitmap(oImageBlob);
var iWidth = Math.round( ( img.width / img.height ) * iHeight);
var canvas = new OffscreenCanvas(iWidth,iHeight);
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
var oImageBitmap = canvas.transferToImageBitmap();
ctx = null;
canvas = null;
iWidth = null;
img = null;
return(oImageBitmap);
}
任何帮助都是非常感谢的。
1条答案
按热度按时间zxlwwiss1#
For the ImageBitmap to release its bitmap data the most efficient way, you have to call its
.close()
method once you're done with it.But actually, you don't need this
scaleImage
function.createImageBitmap()
has aresizeHeight
option, and if you use it without theresizeWidth
one, you'll resize your image by keeping the aspect-ratio exacty like you are doing in your function, except that it won't need to assign the bitmap twice.Once you have this resized ImageBitmap, you can transfer it to a BitmapRenderingContext (which will internally
close()
the original ImageBitmap) and call thetransferToBlob()
from that renderer. This should be lighter for your computer.