- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
更新
由于在询问以下问题并找到代码中的错误后遇到了一个更基本的问题,因此我在MDN Web文档中找到了更多信息,例如downloads API方法downloads.download()指出已撤销对象仅在下载文件/ URL之后才执行URL。因此,我花了一些时间试图了解Web扩展是否使下载API onChanged事件对网页的javascript“可用”,并且认为没有。我不明白为什么downloads API仅适用于扩展,特别是当有很多关于此相同的内存使用/对象URL吊销问题的问题时。例如,Wait for user to finish downloading a blob in Javascript。
如果您知道,请您解释一下?谢谢。
从关闭Firefox浏览器开始,然后右键单击本地html文件以在Firefox中打开,它会打开五个firefox.exe进程(在Windows任务管理器中查看)。其中四个进程从20,000k到25,000k的内存开始,而一个进程约有115,000k。
该html页面具有一个indexedDB数据库,其中包含50个对象存储,每个存储包含50个对象。每个对象都从其对象存储中提取出来,并使用JSON.stringify转换为字符串,然后写入二维数组。之后,将数组中的所有元素连接成一个大字符串,转换为blob,然后通过URL对象将其写入硬盘,此后立即将其撤销。最终文件约为190MB。
如果在转换为Blob之前就停止了代码,则firefox.exe进程之一的内存使用量将增加到约425,000k,然后在将数组的元素连接到一个数组后约5-10秒内回落到25,000k。单字符串。
如果代码运行完成,则同一firefox.exe进程的内存使用量将增长到大约1,000,000k,然后下降到大约225,000k。从115,000k开始的firefox.exe进程在代码的blob阶段也会增加到大约325,000k,并且永远不会减少。
在将blob作为文本文件写入磁盘后,这两个firefox.exe进程再也不会释放大约2 x 200,000k的内存增加。
我已经将每个函数中使用的每个变量都设置为null,除非刷新页面,否则永远不会释放内存。同样,此过程是通过按钮单击事件启动的。如果再次运行而没有中间刷新,则这两个firefox.exe进程中的每个进程每次运行都会获取额外的200,000k内存。
我一直无法弄清楚如何释放内存?
这两个功能非常简单。 json [i] [j]保存数据库中第i个对象存储中第j个对象的字符串版本。 os_data []是小型对象数组{“name”:objectStoreName,“count”:n},其中n是商店中对象的数量。如果未调用write_to_disk,则build_text功能似乎会释放内存。因此,问题似乎与Blob或url有关。
我可能忽略了一些显而易见的事情。感谢您提供的任何指导。
编辑:
我从JavaScript: Create and save file看到我的revokeObjectURL(blob)陈述有误。它无法撤消Blob,需要将createObjectURL(blob)保存到类似url的变量中,然后撤消url,而不是blob。
在大多数情况下,这大部分都是有效的,并且内存是从上述两个firefox.exe进程中释放的。这给我留下了一个有关URL撤销时间的小问题。
如果撤销是为了释放内存,那么是否应该仅在成功下载文件之后才撤销URL?如果撤销是在用户单击“确定”下载文件之前发生的,那会发生什么?假设我单击按钮以从数据库准备文件,并且准备好后,浏览器将打开下载窗口,但是我稍等片刻,想着该文件的名称或保存位置,不会撤销声明可以运行,但浏览器仍然保留该url,因为它将下载该内容?我知道我仍然可以下载文件,但是撤销是否仍释放内存?从我对这个示例进行的少量试验来看,在这种情况下似乎没有发布它。
如果有一个事件在文件成功或未成功下载到客户端时触发,那不是应该取消该URL的时间吗?最好在取消URL之前先设置几分钟的超时时间,因为我敢肯定没有事件表明下载到客户端已经结束。
我可能不太了解这方面的基本知识。谢谢。
function build_text() {
var i, j, l, txt = "";
for ( i = 1; i <=50; i++ ) {
l = os_data[i-1].count;
for ( j = 1; j <= l; j++ ) {
txt += json[i][j] + '\n';
}; // next j
}; // next i
write_to_disk('indexedDB portfolio', txt);
txt = json = null;
} // close build_text
function write_to_disk( fileName, data ) {
fileName = fileName.replace(".","");
var blob = new Blob( [data], { type: 'text/csv' } ), elem;
if ( window.navigator.msSaveOrOpenBlob ) {
window.navigator.msSaveBlob(blob, fileName);
} else {
elem = window.document.createElement('a');
elem.href = window.URL.createObjectURL(blob);
elem.download = fileName;
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
window.URL.revokeObjectURL(blob);
}; // end if
data = blob = elem = fileName = null;
} // close write_to_disk
最佳答案
我对这里的问题有点迷茫...
但是,让我们尝试至少回答一下:
首先,让我们解释URL.createObjectURL(blob)
大致做什么:
它创建一个blob URI,这是一个指向内存中Blob blob
的URI,就像它位于可访问的位置(例如服务器)一样。
只要未撤消,此blob URI就会将blob
标记为无法被垃圾收集器(GC)收集,因此您不必在脚本中维护对blob
的实时引用,但是您可以仍然使用/加载它。
然后URL.revokeObjectURL
将断开Blob URI和内存中Blob之间的链接。它不会直接释放blob
占用的内存,只会删除它对GC的保护,[并且不再指向任何地方]。
因此,如果您有多个指向同一Blob对象的Blob URI,则仅吊销一个不会破坏其他Blob URI。
现在,只有在启动GC时,才释放内存,而内存只有在浏览器内部,认为是最佳时间或没有其他选择(通常是错过了内存空间)时才由浏览器内部决定。 )。
因此,您通常不会看到立即释放内存,这是很正常的,根据经验,我想说FF不关心使用大量内存(如果可用),因此不会经常发生GC踢,这对用户体验很有好处(GCing通常会导致滞后)。
对于您的下载问题,确实,Web API不能提供一种方法来知道下载是成功还是失败,甚至是刚刚结束。
对于撤消部分,这实际上取决于您执行操作的时间。
如果直接在点击处理程序中执行此操作,则浏览器将尚未完成预取请求,因此当发生默认的点击操作(下载)时,URI不会链接任何内容不再。
现在,如果您确实在“保存”提示后撤消了Blob URI,则浏览器将完成一个预取请求,因此可能能够自行标记不应清除Blob资源。但是我认为这种行为不受任何规范的束缚,最好至少等待窗口的focus
事件,这时应该已经开始下载资源。
const blob = new Blob(['bar']);
const uri = URL.createObjectURL(blob);
anchor.href = uri;
anchor.onclick = e => {
window.addEventListener('focus', e=>{
URL.revokeObjectURL(uri);
console.log("Blob URI revoked, you won't be able to download it anymore");
}, {once: true});
};
<a id="anchor" download="foo.txt">download</a>
关于javascript - 在将文件写入客户端磁盘时从blob创建/对象URL释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59386102/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!