I noticed that our memory consumption on Android devices is very high (up to 90MB and even more). We are working on a 2d game so our main memory consumption should be textures. Also sound is currently not implemented.
Now when I check how much memory is added (in Android task manager) when I load another of our assets then the consumed memory is much higher than the texture should consume (256x256, 16bit, no mimap, should be 128kB by Unity).
Are there any tips, hints or best practices regarding this topic? Thanks in advance.
My game consumes about 90MB. When I add up all the memory from textures, meshes, etc… I can account for just 20MB, I have no clue where all the rest of the memory is going. The memory profiler seems to be reporting only a fraction of what is being used.
Any help to figure out what is causing memory to go up so much would be greatly appreciated
First you do not read right. Only Unity 3D takes up memory. I guess you do not count that.
Also if your textures is compressed, they will uncompress in the memory when used.
Same is for the sounds.
Also Android is per design made to use the memory that is free.
So I do not think your 20MB is even close what you do use.
I read just fine. Of course Unity 3d runtime takes memory, from the documentation should be 12 MB which can be reduced to 6MB by stripping and using the small mscorlib. Not 70 mb.
The textures are compressed in ETC, or kept as RGBA 16. The ETC are NOT decompressed at all in runtime, they are interpreted as is on the video card. The 20 MB I mention include the decompressed RGBA 16 textures. In fact, if I choose a format not supported in android, I can see a warning saying that the video card does not support that format and that it will decompress the texture and I can see the memory increase.
Sounds are MP3 encoded, which the hardware can read, AND they are streamed from disk, so they do not load and decompress in main memory at all. I can see a big difference if I keep them as uncompressed wav audio.
I am running out of memory, and the app is getting killed sometimes, it is not android taking as much as it can spare.
As stated in my post 20MB is not close to what I use. I can see the RSS at 90 MB. And that is my problem, I cannot account for what is consuming so much memory. Any other game consumes around 40 MB of rss (Resident set size).
Mono has HeapShot, which is a heap profiler that could give me some hints, but there is no way to turn it on in Unity.
I don’t appreciate the condescending “you do not read right”, you don’t know anything about me.
I’m going to take a smack at it and guess. Are you using baked lightmaps? That should help. And the textures should be compressed and in a format that is small and as much detail as needed. A great killer in Mobile is also Unity GUI, not GUI Textures. Physics is also a factor. Anything that might be running in the background and always check your drawcalls, try to keep them small as well.
all compressed stuff needs memory when it do uncompress.
You ask for help and you got some stuff you should look at, but its up to you.
If you think you know all and still get huge problem you should rethink.
Some times even uncompressed stuff take less memory then compressed.
Also they use less cpu. but I guess you do not want to listen…
Thank you, great ideas for things to look at. However:
I am not using light in ANY way at all. There is not even a single light source in my project.
I dont use Unity GUI either, I am using NGUI. Maybe NGUI has some trouble?
Very limited physics, I am doing collision detection using my own AABB algorithm. My terrain is voxel based like Infiniminer. I highly doubt this would be it, since there is nothing I allocate for physics
Drawcalls influence performance AFAIK. Do they affect memory consumption?
The problem I have is that it would all be guessing on my part, that I have no way to actually measure what might be going on.
I often try out different stuff to se how they work on the stuff I make, but I never use that.
Also I try to use as small textures I can, without they look bad.
But the main thing is often what device I target. On new phones 90MB is no big deal. The Samsung S3 has over 800MB. So even if the game use 400MB it is okey in my book. But it still not any reason not to optimize textures and other stuff in the game.
You always use light in a scene. If you not put them there yourself you use ambient light source.
If you did not have any light source your scene would be black.
Unity GUI do sucks, so I agree with you to use other source for that. Myself us Playmaker for that as many of my game logics.
Have you looked if you have any memory leaks in your scripts?
Every drawcall also use memory, but those should be reused.
I have my own shaders, which calculate color based on a per vertex parameter. There are no light sources at all, not even ambient. That is why it is not all black.
The problem with memory leaks is how to find them. I am not aware of any, but there is no way to find them without a heap profiler, other than just staring at code.
Most of my code does not depend on unity at all, and I have managed to run it outside unity, with HeapShot. I don’t see the crazy memory usage that way, and no memory leak.
I suppose it is possible for it to be in the parts that ARE dependent on Unity.
That is not true. you need a light to even see anything. Without light it will be only black.
So even if you think you do not use any light you need to rethink.
What you can do is to make some simple scenes and test out different part, like your script and see what is happen.
It is a hard work, I know that and bugs is no fun to track down.
Maybe it’s because it’s referencing to another program in the background taking resources, that’s a guess as well. Shaders could also be a problem unless you optimized them for mobile devices already before development. Draw calls as said before can affect the resource use to draw the meshes.
Well thats light to.
You can see this like this. If you want to show anything you do it with a light source.
It can be ambient light, a Light source or the object itself.
All things you see is depending one an light.
Think like this.,
You are in a room without any light. there is stuff in the room.
But you do not have any light so all will still be black as you can not see anything.
If you put a light in the room all other stuff in the room will be visible. Some will be darker then other depending on the light.
You can also have an object that produce light(Glowing).
Bottom line is that you need any kind of light if you want it to be other then black. Black = no light.
This shader will look red no matter what ambient light is set to or if there are light sources in the scene.
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
return o;
}
half4 frag (v2f i) : COLOR
{
return half4 (1,0,0, 1);
}
This is an oversimplification of what I am doing. But just like my code, it does not use any light at all.
I have no shadows or anything else going on.
Yes, I will have to start from scratch a new scene and add things slowly. Without a decent profiler, it looks like that is the only way to figure it out for sure. I was hopping I could avoid this, but I don’t see how. Thanks for the suggestion.