首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >heroku服务器上的Konva图像使用RSS内存

heroku服务器上的Konva图像使用RSS内存
EN

Stack Overflow用户
提问于 2022-01-23 16:05:03
回答 1查看 104关注 0票数 1

我一直在研究一个不和谐的机器人来生成图像附件并将它们发送到通道中,这一切都很好。然而,我现在遇到了一个问题,当我使用图像,在本例中,32张图片作为附件--“RSS”内存--按照process.memoryUsage.rss()到达的顶部;如果我运行这个过程2-3次,服务会因内存不足而失效。

所以这一切都在一个节点过程中,在Heroku上。

“守则”原则上:

代码语言:javascript
复制
  let stage = new Konva.Stage({
    width: width,
    height: height,
  });

  let canvas1 = createCanvas(stage.width(), stage.height());
  const ctx1 = canvas1.getContext('2d'); // I draw to this

  let canvas2 = createCanvas(stage.width(), stage.height());
  const ctx2 = canvas2.getContext('2d'); // I draw to this

  let layer = new Konva.Layer();

  ...

  // It's these images that seem to cause the most Memory Bloat
  Konva.Image.fromURL(
    imagePath,
    imageNode => {
      imageNode.setAttrs(attrs); // attrs = { image, x, y, width, height }
      layer.add(imageNode);      
      // imageNode.destroy(); doesn't save memory
    }
  );

  ...

  // Add the canvas to the Konva, as an image
  layer.add(new Konva.Image({
    image: canvas1,
    x: 0,
    y: 0,
    width: stage.width(),
    height: stage.height(),
    opacity: 0.5,
  }));

  // Add the canvas to the Konva, as an image
  layer.add(new Konva.Image({
    image: canvas2,
    x: 0,
    y: 0,
    width: stage.width(),
    height: stage.height(),
    opacity: 0.5,
  }));

  ...

  stage.add(layer);
  layer.draw();
  let asCanvas = stage.toCanvas(); // I use this for the attachment

  stage.destroy();
  stage = null;
  layer = null;

  return asCanvas;

  ...

  
  let attachment = new Discord.MessageAttachment(
    fromAsCanvas.toBuffer(), // fromAsCanvas is from the asCanvas above.
    'imageName.png'
  );

  message.channel
    .send({
      files: [attachment],
      content: 'Message with the Attachment',
    });

我当时的想法是,从系统加载的图像,然后添加到图层,然后放到画布上,不会从内存中释放出来,只是在没有一致性的情况下在那里坐上相当长的时间。

我试过:

之后运行垃圾收集器以确认这是否有帮助(它执行not)

  • Destroying图像后添加到层(这删除了图像itself)

  • Destroying,Stage

  • Destroying,Layer

  • Nulling,舞台,层,以及所有4个与画布相关的变量

)。

我有很多日志,例如:

代码语言:javascript
复制
Start: 74MB
Post ctx1: 75MB
Post ctx2: 75MB
Post Reduce: 77MB
Post forEach: 237MB // adds all 32 the images +160MB
Post Mark Destroyed Guns (spread arrays): 237MB
Post Added Some Things 1: 247MB +10MB
Post Added Some Things 2: 249MB
Post Added Some Things 3: 259MB
Post Added Some Things 4: 260MB
Post Add canvas1 Canvas to Layer: 260MB
Post Add canvas2 to Layer: 260MB
Post Add Layer to Stage: 293MB +33MB
Post Layer.draw: 294MB
Post toCanvas: 321MB +27MB
Post Destroy Stage/etc: 308MB -13MB
Sends message
5 Seconds later RSS is at: 312MB +4MB

正如您所看到的,一旦解决了这个问题,我可能还有50 to的额外内存需要调试。

EN

回答 1

Stack Overflow用户

发布于 2022-01-26 10:01:42

我相信我现在已经解决了这个问题,基于本文:https://github.com/Automattic/node-canvas/issues/785 --基本上,我在“onload”语句中添加了img.onload = null;语句,因为我在尝试解决这个问题时重构到了一个承诺/onload系统中。

后续行动1:

除了设置img.src = null之外,我还接着进行了以下操作:

代码语言:javascript
复制
process.nextTick(() => {
  img.onload = null;
  img.onerror = null;
  img = null;
})

img = null的设置带来了更多的内存,但仍然占用了大量内存。

后续行动2:

我发现破坏图层和图像也有助于释放更多的内存,以至于我似乎最终在进程之间恢复了内存:

代码语言:javascript
复制
layer.destroyChildren();
layer.destroy();
stage.destroyChildren();
stage.destroy();
stage = null;
layer = null;

我希望,这个问题终于解决了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70823980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档