hajimehoshi / ebiten

Ebitengine - A dead simple 2D game engine for Go
https://ebitengine.org
Apache License 2.0
11.13k stars 665 forks source link

Very high and increasing memory usage in browser (wasm) but not as normal executable. #1497

Open oderwat opened 3 years ago

oderwat commented 3 years ago

I am working on a small game for some weeks, and every since I started, I noticed that it is using a huge amount of memory running in Google Chrome (and on the iPhone Safari, too, it seems). It won't even start in Firefox or Edge (out of memory error).

Even if I do "nothing" than drawing a static image (intro logo), the RAM usage increases in quarter GB steps, after some short time, there are 30+ GB of memory usage, which immediately vanish when closing the browser tab running the game.

The same code uses a fraction of memory running just from the terminal (and for hours).

Does anybody know what could be wrong there or what's the best way to find out whats the problem here?

The same happens with the last release and master.

hajimehoshi commented 3 years ago

If the virtual memory is used, it should be fine even though the memory consumes 30GB or so. If the physical memory is used, this might be a problem.

What about testing a hello-world wasm program in Go without Ebiten?

oderwat commented 3 years ago

Well, it is listed as physical memory for the google chrome renderer. When I do memory profiling the JS VM, it just has a few megabytes and shows allocations when I play.

image

I need to find the smallest version to test.

You could try it by yourself at https://beta.numrix.oderwat.de/ when I didn't destroy it while working on it.

hajimehoshi commented 3 years ago

You could try it by yourself at https://beta.numrix.oderwat.de/ when I didn't destroy it while working on it.

Thanks, but Chrome warned this site's certification.

oderwat commented 3 years ago

Sure it uses a self-signed certificate. You can just go to http://beta.numrix.oderwat.de/ and not have the warning/encryption through SSL. In the end, it does not really matter. I had used an SSL certificate because some browsers don't allow audio output from iframes if there is no SSL connection.

BTW: This is how they make money because having a self-signed certificate does the same level of encryption but didn't "validate the owner" of the site. Most of the time, it is not really checked by the sellers of certificates, as they only check if you have access to the DNS or E-Mails on that Domain.

hajimehoshi commented 3 years ago

I think you are using macOS. How did you show the physical memory?

I showed 'Real memory' with your application, and I didn't see such memory consuming.

Chrome's task manager (probably showing virtual memory usages) image

macOS's activity monitor (showing virtual memory usage and real (physical?) memory) image

oderwat commented 3 years ago

I just checked in Chrome on my new Macbook Air M1, and there it shows more like your values. I also use the activity monitor as your lower image.

My iMac, where it shows the higher values, has 128 GB of RAM. Maybe it has to do with that. Still, I get out of memory in Firefox and Edge directly after loading the page. Also, running on the iPhone uses the battery up in just some minutes and continues even if I close the app, which is another bizarre effect.

Thank you for looking into it. I may try some stuff to get more specific.

hajimehoshi commented 2 years ago

I think the situation should be better with the latest version v2.4.2, as https://github.com/hajimehoshi/ebiten/issues/2156 was fixed.

@oderwat Could you check the latest version when you are available? Thanks,

oderwat commented 2 years ago

Hi @hajimehoshi, glad to see you coming back to that problem. I just updated everything (I was not touching it for a long time) and wanted to make some tests, but I ran into a problem with transparency. The alpha channel rendering as follows does not work anymore:

cellImg.Fill(color.RGBA{0xff, 0xff, 0, 0x10})

It is only 0 = full transparent. Everything else gets me the full color. Is that known/documented, or is that some bug?

Testing it on my iPhone (same code as before), it works for some time, but then it crashes after some seconds. Independent of using the app or not. I also do not have audio. It also seems to draw some CPU and gets hot, even without doing anything (just showing the static loading screen in Safari).

This newly compiled version is under the same URL as mentioned above.

P.S.: I was about to implement this using Go-App and "raw" canvas or even just HTML5 in the future.

If you want to look into the code or use it for tests, I can invite you to the repository.

hajimehoshi commented 2 years ago

Hi @oderwat

cellImg.Fill(color.RGBA{0xff, 0xff, 0, 0x10})

This value doesn't make sense as a premultiplied alpha color. RGB value should not exceed the alpha value (See also https://github.com/hajimehoshi/ebiten/issues/2080).

cellImg.Fill(color.RGBA{0x10, 0x10, 0, 0x10}) or cellImg.Fill(color.NRGBA{0xff, 0xff, 0, 0x10}) should work.

Thanks,

oderwat commented 2 years ago

Than you @hajimehoshi

I was not aware of the premultiplication, and as it worked before, I didn't think it was wrong :). This is fixed now!

Sadly, the memory problems are still there. Do you know how to find the culprit (I am probably just doing something else wrong)?

hajimehoshi commented 2 years ago

Sadly, the memory problems are still there. Do you know how to find the culprit (I am probably just doing something else wrong)?

If you use Chrome, Chrome's profiling tool should be helpful.

EDIT: Now there is a bug in wasmserve and function names are not available. I'm working on this.

On desktops, you can use go tool pprof.

hajimehoshi commented 2 years ago

Another tips are:

oderwat commented 2 years ago

I removed the last call to ebiten.NewImage* in the render routine and do no poking at pixels anyway. On native OSX, the app is reported with less than 50 MB and stays constant, no matter how long it runs and is being used.

In Chrome, it is the same:

image

In iOS Safari, it loads the page, and if I don't use the app, it will always run for some time, crash, and then restart the page. While using Safari Dev Tools connected to my phone, I could not find any error message. An instruments memory trace using instruments does not seem to reveal a lot (I am not experienced with that).

image

As I said, it gets pretty hot, which seems to be what the instrument's status also finds. Maybe it is not about the memory after all, then? Or it was with older versions and my former newImage heavy code. The app shows that it runs with 6ß fps and 20 tps.

It seems stable on a very cheap Android (up-to-date) phone that we use for testing Wasm PWAs in the low-budget category. But the sound is not working well, and the interface is sluggish. But after some time, it crashes there too. I did not try to figure out how to instrument that.

hajimehoshi commented 2 years ago

I agree this is not a memory issue but a CPU issue. 20TPS on iOS Safari seems pretty low.

You can take a profile to know what function is heavy like this:

image

If you use wasmserve, please update like this:

go install github.com/hajimehoshi/wasmserve@aab823156ca2de50a7e60bff23d3c46f49a16a19
oderwat commented 2 years ago

I serve the Wasm using Nginx as part of all my other servers. The TPS is what I set to make it "less likely" that it takes a lot of CPU. I also do not have screen updates besides outputting the FPS/TPS/Redraw values with text.Draw() and ebitenutil.DrawRect(). But I made progress after going through all code and removing deprecated functions. I did not evaluate what exactly stopped the app from crashing, but I suspect the older ebiten.TouchIDs().

Now I am left with audio problems. It works fine on Mac Desktop in Chrome. I do not get any sound on iOS, and I get sound, but it does not play correctly (for example, it loops or mangles the sound instead of just playing it once). I did not have time to check more details.

P.S.: I am using your wasm audio package solo in another project without problems, so I know it can work.

tslocum commented 4 months ago

Update: My issue is caused by a WebSocket library and is not related to Ebitengine.


Hello,

I am running into this issue as well in boxcars. You can reproduce this using v1.3.6. Any browser-specific code is located in this file.

When running as a Linux binary, memory usage remains low.

When running in a browser, memory usage steadily increases by 1 or 2 megabytes every few seconds, even when no additional memory is being allocated by the game. I reproduced this using Firefox 127.0 on Gentoo, and based on user reports this also affects Firefox on Fedora.

This may be a Go compiler issue rather than an Ebitengine issue. I am glad to help investigate, just let me know what I can do to help.

Thanks, Hajime, for all that you do.

hajimehoshi commented 4 months ago

I hope someone could make a minimized case to reproduce this issue. Thanks

tslocum commented 4 months ago

While creating a minimal case I've found my issue is actually caused by a WebSocket library and not Ebitengine. Sorry for the noise.