A ver si alguien me puede prestar ayuda para encontrar una posible fuga de memoria en este script.
El código lo he sacado de este gadget para windows, y lo que hace es monitorizar el estado de los dispositivos conectados (el espacio libre de almacenamiento):
http://win7gadgets.com/pc-system/sushis_driveinfo.html
Creo que el problema está al dibujar las imágenes, la parte donde maneja los objetos de las imágenes, el cual bajo mi punto de vista parecen ser correctamente liberados en cada operación, aunque mi nivel de javascript es practicamente nulo, me guio por la sintaxis, así que quizás estoy omitiendo algo importante que no consigo ver, de hecho seguramente así espero que sea, ya que el tamaño no deja de incrementarse, si dejas el gadget corriendo 24 horas puede llegar a superar incluso el 1 GB de consumo de RAM, mientras que con otros gadgets del mismo tipo...esto no sucede, así que dudo que sea un problema del sidebar.exe, y no del Gadget.
Es horrible que el desarrollador de este Gadget no se haya dado cuenta de eso en +4 años de desarrollo y actualizaciones (este gadget es una re-version de un gadget anterior y con nombre parecido, del 2009 o 2010), espero que yo pueda hacer algo para arreglarlo, con vuestra ayuda.
sushi_driveinfo.html
Código
<html> <head> <title>Drive Info</title> <style> body { margin: 0; padding: 0; width: 156px; height: 200px; background-image: url(images\canvas.png); color: #ffffff; font-family: 'Segoe UI'; } #targets { position: absolute; top: 0; left: 0; } .target { position: absolute; width: 156px; height: 48; left: 0; cursor: hand; } </style> <script type="text/javascript"> var lst = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var timeout = null; var drives = new Array(26); var drvchk = new Array(26); var drvspc = new Array(26); var vizchg = false; var current_y = 0; var background,theme,remove,local,network,media,show_pc,show_net; var item_height=48; var icon_offset=20; var text_offset=72; var meter_offset=24; function convertBytes(b) { var i = 0, u = Array(' MB', ' GB', ' TB'); while (b >= 1024 && (b /= 1024) >= 1) i++; return (Math.round(b * 100) / 100) + u[i]; } function openDrive() { var d = window.event.srcElement.getAttribute('drive'); System.Shell.execute(d + ':\\'); return; } function openNetwork() { System.Shell.execute("Explorer", "/N,::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}"); return; } function openComputer() { System.Shell.execute("Explorer", "/N,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"); return; } function recheckDrives() { for(var i = 0; i < 26; i++) { if (!drives[i]) { drives[i] = System.Shell.drive(lst.charAt(i)); if (drives[i]) { vizchg = true; drvchk[i] = true; } } else { if (drives[i].isReady != drvchk[i]) { drvchk[i] = !drvchk[i]; vizchg = true; } if (drives[i].isReady && drives[i].freeSpace != drvspc[i]) { drvspc[i] = drives[i].freeSpace; vizchg = true; } } } } function calcHeight(h) { var y=0; if(show_pc==2) y+=h; if(show_net==2) y+=h; for(var i=0;i<26;i++) if(isDriveVisible(i)) y+=h; return y; } function isDriveVisible(i) { if(drvchk[i]) { if (drives[i].driveType == 2 && remove == 1) ; else if (drives[i].driveType == 3 && local == 1) ; else if (drives[i].driveType == 4 && network == 1) ; else if (drives[i].driveType == 5 && media == 1) ; else if (drives[i].driveType == 1 || drives[i].driveType == 6) ; else return true; } return false; } function paintPC() { if (show_pc == 2) { canvas.addImageObject('images/backgrounds/background' + background + 's.png', 0, current_y); var di=canvas.addImageObject('images/drives/pc'+ theme +'.png', icon_offset, current_y); di.width*=0.8; di.height*=0.8; canvas.addTextObject('Computer', 'Segoe UI', 11, 'white', text_offset, current_y + 5); var b = document.createElement('DIV'); b.className = 'target'; b.style.posTop = current_y; b.onclick = openComputer; targets.appendChild(b); current_y+=item_height; } return; } function paintNET() { if (show_net == 2) { canvas.addImageObject('images/backgrounds/background' + background + 's.png', 0, current_y); var di=canvas.addImageObject('images/drives/net'+ theme +'.png', icon_offset, current_y); di.width*=0.8; di.height*=0.8; canvas.addTextObject('Network', 'Segoe UI', 11, 'white', text_offset, current_y + 5); var b = document.createElement('DIV'); b.className = 'target'; b.style.posTop = current_y; b.onclick = openNetwork; targets.appendChild(b); current_y+=item_height; } return; } function paintGadget() { try { recheckDrives(); if (!vizchg) return; var total_height=calcHeight(item_height); System.Gadget.beginTransition(); document.body.style.height=total_height; canvas.style.height=total_height; canvas.removeObjects(); targets.innerHtml = ''; current_y = 0; paintPC(); paintNET(); for(i = 0; i < 26; i++) { if(isDriveVisible(i)) { if (drives[i].freeSpace != 0) { canvas.addImageObject('images/backgrounds/background' + background + '.png', 0, current_y); var f = Math.round(drives[i].freeSpace / drives[i].totalSize * 100); var u = (100 - f); canvas.addTextObject(convertBytes(drives[i].freeSpace) + ' / ' + f + '%', 'Segoe UI', 10, 'white', text_offset, current_y + 17); var m = canvas.addImageObject('images/meter' + (u < 90 ? 'blue': (u < 98 ? 'orange': 'red')) + '.png', meter_offset, current_y + 34); m.width = Math.floor((u * 128 / 100)); m.left = 24 - Math.floor(((128 - m.width) / 2)); } else { canvas.addImageObject('images/backgrounds/background' + background + 's.png', 0, current_y); canvas.addTextObject(convertBytes(drives[i].totalSize), 'Segoe UI', 10, 'white', text_offset, current_y + 17); } var di=canvas.addImageObject('images/drives/drive' + drives[i].driveType + theme + '.png', icon_offset, current_y-5); di.width*=0.8; di.height*=0.8; canvas.addTextObject(drives[i].volumeLabel + ' (' + drives[i].driveLetter + ':)', 'Segoe UI', 11, 'white', text_offset, current_y + 5); var o = document.createElement('DIV'); o.className = 'target'; o.style.posTop = current_y; o.setAttribute('drive', drives[i].driveLetter); o.onclick = openDrive; targets.appendChild(o); current_y += item_height; } System.Gadget.endTransition(System.Gadget.TransitionType.morph,0.1); window.setTimeout(fixCanvasBackground, 600); } } finally { vizchg = false; return; } } function fixCanvasBackground() { canvas.src = canvas.src; } function initDrives() { for(var i = 0; i < 26; i++) { drives[i] = System.Shell.drive(lst.charAt(i)); if (drives[i] && drives[i].isReady) { drvchk[i] = true ; drvspc[i] = drives[i].freeSpace; } else { drvchk[i] = false; } } return; } function onShowSettings() { window.clearInterval(timeout); System.Gadget.beginTransition(); window.setTimeout(endTransitionFast, 400); } function onSettingsClosed() { readSettings(); timeout=window.setInterval(paintGadget, 2500); vizchg=true; paintGadget(); } function endTransitionFast() { System.Gadget.endTransition(System.Gadget.TransitionType.morph, 0.1); fixCanvasBackground(); } function readSettings() { background=System.Gadget.Settings.read("background"); if(background==0) { background=2; System.Gadget.Settings.write("background",2); } theme=System.Gadget.Settings.read("theme"); if(theme==0) { theme=1; System.Gadget.Settings.write("theme",1); } show_pc=System.Gadget.Settings.read("showpc"); if(show_pc==0) { show_pc=1; System.Gadget.Settings.write("showpc",1); } show_net=System.Gadget.Settings.read("shownet"); if(show_net==0) { show_net=1; System.Gadget.Settings.write("shownet",1); } local=System.Gadget.Settings.read("local"); if(local==0) { local=2; System.Gadget.Settings.write("local",2); } media=System.Gadget.Settings.read("media"); if(media==0) { media=2; System.Gadget.Settings.write("media",2); } network=System.Gadget.Settings.read("network"); if(network==0) { network=2; System.Gadget.Settings.write("network",2); } remove=System.Gadget.Settings.read("remove"); if(remove==0) { remove=2; System.Gadget.Settings.write("remove",2); } } function onLoad() { System.Gadget.settingsUI = "settings.html"; System.Gadget.onSettingsClosed = onSettingsClosed; System.Gadget.onShowSettings = onShowSettings; readSettings(); initDrives(); timeout = window.setInterval(paintGadget, 2500); vizchg = true; paintGadget(); return; } </script> </head> <body onload="onLoad()"> <div id="targets"></div> <g:background id="canvas" src="images/canvas.png" style="position: absolute; top: 0; left: 0; width: 156; height: 200; z-index: -999;" opacity="0" /> </body> </html>
Luego está este otro html, pero por el nombre de los eventos y que además parece estar relacionado unicamente con la ventana de la configuración del gadget, es decir, que los eventos suceden muy esporádicamente o nunca... solo para dibujar el background de la ventana de configuración del gadget, entonces yo diría que poco o nada tiene que ver todo este código con la fuga:
settings.html
Código
<html> <head> <style> body { width: 250px; height: 800px; padding: 0px; margin: 0px; font-family: Tahoma; } body,p,div,span,td { font-size: 9pt; } label { font-weight: bold; } input,select { font: Arial; font-size: 9pt; } table { width: 100%; } </style> <script> var background, maxBackgrounds = 3, theme = 1, maxThemes = 7; function updateBackground() { var x = 84, y = 47, m; canvas.removeObjects(); canvas.addImageObject('images/backgrounds/background' + background + '.png', x, y); m = canvas.addImageObject('images/meterblue.png', x + 24, y + 34); m.width = (0.25 * 128); m.left = x + 24 - ((128 - m.width) / 2); canvas.addImageObject('images/drives/drive3' + theme + '.png', x, y); canvas.addTextObject('Vista (C:)', 'Segoe UI', 11, 'white', x + 58, y + 5); canvas.addTextObject('40GB / 75%', 'Segoe UI', 10, 'white', x + 58, y + 17); //y -= 20; //canvas.addImageObject('images/backgrounds/background' + background + '.png', x, y); //m = canvas.addImageObject('images/meterorange.png', x + 24, y + 34); //m.width = (0.937 * 128); //m.left = x + 24 - ((128 - m.width) / 2); //canvas.addImageObject('images/drives/drive3.png', x, y); //canvas.addTextObject('Apps (D:)', 'Segoe UI', 11, 'white', x + 58, y + 5); //canvas.addTextObject('10GB / 6.3%', 'Segoe UI', 10, 'white', x + 58, y + 17); canvas.addImageObject('images/drives/drive3' + theme + '.png', x-85, y+130); canvas.addImageObject('images/drives/drive2' + theme + '.png', x-85, y+172); canvas.addImageObject('images/drives/drive4' + theme + '.png', x-85, y+215); canvas.addImageObject('images/drives/drive5' + theme + '.png', x-85, y+258); } function onBackground() { var e = window.event, o = e.srcElement, b = o.getAttribute('base'); o.src = 'images/settings/' + b + (e.type == 'mouseover' || e.type == 'mouseup' ? 'hover': (e.type == 'mousedown' ? 'pressed': '')) + '.png'; if (e.type == 'mouseup') { if (b == 'next') background++; else background--; if (background < 1) background = maxBackgrounds; if (background > maxBackgrounds) background = 1; updateBackground(); } } function onTheme() { var e = window.event, o = e.srcElement, b = o.getAttribute('base'); o.src = 'images/settings/' + b + (e.type == 'mouseover' || e.type == 'mouseup' ? 'hover': (e.type == 'mousedown' ? 'pressed': '')) + '.png'; if (e.type == 'mouseup') { if (b == 'next') theme++; else theme--; if (theme < 1) theme = maxThemes; if (theme > maxThemes) theme = 1; updateBackground(); } } function onClose(event) { if (event.closeAction == event.Action.commit) { System.Gadget.Settings.write("background", background); System.Gadget.Settings.write("theme", theme); System.Gadget.Settings.write("showpc", document.boxes.mypc.checked ? 2 : 1); System.Gadget.Settings.write("shownet", document.boxes.netw.checked ? 2 : 1); System.Gadget.Settings.write("remove", document.boxes.remove.checked ? 2 : 1); System.Gadget.Settings.write("local", document.boxes.local.checked ? 2 : 1); System.Gadget.Settings.write("network", document.boxes.network.checked ? 2 : 1); System.Gadget.Settings.write("media", document.boxes.media.checked ? 2 : 1); } event.cancel = false; // System.Gadget.beginTransition(); // window.setTimeout(endtransit, 400); } /* function endtransit() { System.Gadget.endTransition(System.Gadget.TransitionType.morph, 0.1); }*/ function onLoad() { var box; System.Gadget.onSettingsClosing = onClose; background = System.Gadget.Settings.read("background"); if (background == 0) background = 2; theme = System.Gadget.Settings.read("theme"); if (theme == 0) theme = 1; System.Gadget.Settings.read("remove") == 2 ? document.boxes.remove.checked = true : false; System.Gadget.Settings.read("local") == 2 ? document.boxes.local.checked = true : false; System.Gadget.Settings.read("network") == 2 ? document.boxes.network.checked = true : false; System.Gadget.Settings.read("media") == 2 ? document.boxes.media.checked = true : false; System.Gadget.Settings.read("showpc") == 2 ? document.boxes.mypc.checked = true : false; System.Gadget.Settings.read("shownet") == 2 ? document.boxes.netw.checked = true : false; updateBackground(); } </script> </head> <body onload="onLoad()"> <g:background id="canvas" src="images/settings/desktop.png" style="position: absolute; left: 1; top: 1; z-index: -999;" /> <div style="position: absolute; left: 0; top: 147px;"> <table cellspacing="0" cellpadding="0"> <tr> <td style="width: 33%; padding-right: 10px;" align="right"><img src="images/settings/previous.png" base="previous" style="cursor: hand;" onmouseover="onBackground();" onmouseout="onBackground();" onmousedown="onBackground();" onmouseup="onBackground();" /></td> <td style="width: 33%;" align="center"><label>Backgrounds</label></td> <td style="width: 33%; padding-left: 10px;" align="left"><img src="images/settings/next.png" base="next" style="cursor: hand;" onmouseover="onBackground();" onmouseout="onBackground();" onmousedown="onBackground();" onmouseup="onBackground();" /></td> </tr> <tr> <td style="width: 33%; padding-right: 10px;" align="right"><img src="images/settings/previous.png" base="previous" style="cursor: hand;" onmouseover="onTheme();" onmouseout="onTheme();" onmousedown="onTheme();" onmouseup="onTheme();" /></td> <td style="width: 33%;" align="center"><label>Icon Theme</label></td> <td style="width: 33%; padding-left: 10px;" align="left"><img src="images/settings/next.png" base="next" style="cursor: hand;" onmouseover="onTheme();" onmouseout="onTheme();" onmousedown="onTheme();" onmouseup="onTheme();" /></td> </tr> </table> <table cellspacing="0" cellpadding="0" style="margin-top: 15px;margin-left:60px;"> <tr><td> <form name="boxes"> <input type="checkbox" name="local"> <font style="font-size: 8pt;">Local Drives</font><p> <input type="checkbox" name="remove"> <font style="font-size: 8pt;">Removable Drives</font><p> <input type="checkbox" name="network"> <font style="font-size: 8pt;">Network Drives</font><p> <input type="checkbox" name="media"> <font style="font-size: 8pt;">Media Drives</font><p> <input type="checkbox" name="mypc"> <font style="font-size: 8pt;">My Computer link</font><br> <input type="checkbox" name="netw"> <font style="font-size: 8pt;">Network Link</font> </form> </td></tr> </table> </div> </body> </html>