为什么只有在执行绘制操作时才能达到画布的最大内存

时间:2018-10-12 21:26:10

标签: javascript ios memory html5-canvas

在iOS上,画布的最大分配内存为memSize()/4,通常可解析为256mb

现在考虑以下代码:

const createImage = () => {
  const size = 512

  const canvas = document.createElement('canvas')
  canvas.height = size
  canvas.width = size
  document.body.appendChild(canvas)
}

const createImages = nbImage => {
  let count = 0
  for (let i = 0; i < nbImage; i++) {
    try {
      createImage()
      count = count + 1
    } catch (e) {
      console.log(i, e)
      break
    }
  }
  console.log(`done for ${count} MB`)
  console.log(`there are ${nbImage - count} remaining canvas to create...`)
}

createImages(500)

在我的iPhone 8输出上运行它:

done for 500 MB
there are 0 remaining canvas to create...

将createImage更改为此:

const createImage = () => {
  const size = 512

  const canvas = document.createElement('canvas')
  canvas.height = size
  canvas.width = size
  const ctx = canvas.getContext('2d')
  ctx.fillStyle = 'red'
  ctx.fillRect(0, 0, size, size)
}

您将获得如下所示的输出:

Total canvas memory use exceeds the maximum limit (256mb).
256 - TypeError: null is not an object (evaluating 'ctx.fillStyle = 'red'')
done for 256 MB
there are 244 remaining canvas to create...

请注意,我在第二个版本的createImage中删除了appendChild

如果有任何剩余的画布要创建,我事件将在60秒后尝试再次调用createImages函数:

if (count < nbImage) setTimeout(createImages, 60000, nbImage - count)

看看在此期间GC是否有时间收集,但无济于事。

我知道,如果我将我的createImage更改为此:

const createImage = () => {
  const size = 512

  const canvas = document.createElement('canvas')
  canvas.height = size
  canvas.width = size
  const ctx = canvas.getContext('2d')
  ctx.fillStyle = 'red'
  ctx.fillRect(0, 0, size, size)
  canvas.height = 0
  canvas.width = 0
}

创建了500个画布,但问题是我最终想将我的画布附加到dom上,在这种情况下,实际上不可能将其宽度和高度重置为0。

有见识吗?

1 个答案:

答案 0 :(得分:0)

为什么当他们还不知道实际需要多少内存甚至必须分配任何内存时,为什么还要为位图分配任何内存呢?

在初始化上下文之前,画布不像任何元素一样保留位图缓冲区。

上下文可以是webgl上下文(需要分配2个位图缓冲区),2d上下文(1个缓冲区)或ImageBitmapRenderer(无位图缓冲区)。

因此,您的观察很有意义。