Why so large allocation for StaticMesh on Dedicated Server?

I have problems with a large size of StaticMesh in the memory report on the dedicated server. A typical report will say for example (one output of “obj list class=StaticMesh” console command)

StaticMesh /Game/Environment/CraddleOfVictors/Meshes/Bridge_LOD0.Bridge_LOD0 2.61 2.99 50587.15 0.07 0.00 0.00 0.00 50587.07

which should be read that the bare StaticMesh takes up 2.61 kB but its subresources take up more than 50MB. The mesh has collision complexity set to “Use Simple as Complex” and a series of bounding boxes, and the Collision is disabled on the mesh.

I have several of such resources, some taking very little extra memory (10 kB) while others taking many MBs. After debugging the issues, I found that those resources that have more than one UV channel imported suffer from those issues on the dedicated server.

I also assembled a minimal project where you can check if this issue occurs. Here are the steps to reproduce the error:

  1. Create an empty project

  2. Create a new map where you place in the StaticMesh asset. I use Bridge (created in Blender, only simple collision): a) no LODS, b) no materials, and c) with LODS.

  3. Add source file (so it converts it to code project)

  4. Add a dedicated server build target: GameNameServer.Target.cs (with appropriate build commands, check the project included)

  5. Package the project

  6. Build the Server Version and copy to Game/Binaries/Win32/GameNameServer.exe (you will need Git source distribution for this step)

  7. Run the server with -messaging flag

  8. Using Unreal Frontend, attach to the server and run “memreport -all” command

The project can be downloaded from https://drive.google.com/open?id=0B3uwjh5Rndl9OC1vWmtiUFZvNUU

I get the following results for a mesh with 500k triangles, 270k vertices and 2 UV channels:
StaticMesh /Game/Environment/CraddleOfVictors/Meshes/Bridge_LOD0.Bridge_LOD0 2.61 2.99 50587.15 0.07 0.00 0.00 0.00 50587.07
StaticMesh /Game/Environment/CraddleOfVictors/Meshes/Bridge_LOD_NoMaterial.Bridge_LOD_NoMaterial 2.61 2.99 50587.15 0.07 0.00 0.00 0.00 50587.07
StaticMesh /Game/Environment/CraddleOfVictors/Meshes/Bridge_NoLOD.Bridge_NoLOD 2.61 2.99 38461.38 0.07 0.00 0.00 0.00 38461.30

The material is correctly culled on the server and reducing the number of LODS reduces the memory footprint so the error is probably related to the buffers loaded on the server (the should probably not even be touched, so there is also additional CPU cost related to this). I estimate that these buffers take 13+ floats for each vertex (color, normal, 2x texcoord, position), therefore 52 bytes * 270k = 14MB for vertices and probably similiar amount for indices which is really close to 38MB reported for only maximum LOD.

Is there an easy fix to “remove all buffers” on dedicated server? I guess they are needed for complex collision in some situations but I do not need them in my project (probably that messes up the import)? Also I would also prefer the data is not even loaded. I can help you resolve this issue but I would like to know where should this be properly adjusted.

Hey ,

I’d recommend looking into using the Reference Viewer to see what your mesh is referencing and see if there are any optimizations you can make. It isn’t uncommon for assets to reference things that they don’t actually use, and removing these references will definitely increase your efficiency.

What you’ve described in this thread doesn’t necessarily seem like a bug, it seems like you have an asset that is moderately-sized and is using up a fair bit of memory. However, if you can describe exactly what you believe the bug is here then it is possible I’m misunderstanding what you’re saying in your original post.

Have a look at the documentation on the reference viewer and see if there are optimizations you can make to ensure that your assets are as efficient as possible:

Have a great day

1 Like

Hey Sean,

the objects in the reference viewer (or even better, the subojects from the size map) are really small so I still think this is a bug. Let me try to clarify better this time.

A normal StaticObject asset is composed of several subobject (physical body …) as well as several buffers that represents vertices, normals, texture coordinates etc. On a client, when you reference StaticObject, you load everything into RAM and then send some parts to the GPU (and release them from RAM if CPUAccess is false). Now on the dedicated server, you don’t need the buffers. I claim that when the dedicated server is run, the system works as intended when you have one texture coordinate only: the memory footprint for the object is at most a few kBs to hold collision data (simplified collision) but the buffers are not loaded/present.

The main problem occurs when you load a mesh with more than one texture coordinate on the dedicated server: in this case, all buffers stay in the memory forever (even though they are not used). I would like to also get rid of that memory footprint for our game.

Thanks for the clarification. Due to the holiday, many of our developers are out of the office, but once they return I’m going to discuss this with them and I’ll get back to you as soon as I have new information.

We appreciate your patience.

I am bumping this thread since I still haven’t been able to resolve it on my own. Any way to proceed would be greatly appreciated.

Sorry for the delay, with the holidays the developers have been catching up on some work. I’ve reached out a second time to our rendering devs for further information, and I’ll get back to you as soon as I hear back from them.

Thanks for your patience

I’ve received a response, and they are asking that you run the server under a debugger and make sure that StripFlags.IsDataStrippedForServer() is true for you when loading the level and that relevant Init functions on LOD/Render data of static mesh are not being called.

Let me know what the results of your test are.

Thanks

Ok, I feel kind of stupid now. My way of creating dedicated server was totally wrong. I made the normal build (from engine, Package) and then build the server code from Visual Studio and pasted it into WindowsNoEditor/Binaries/Win64 folder. Of course the content was cooked for the client …

For anyone else strugling with this, the solution is very simple: package a game specifically for the dedicated server and do not use that paste trick (unless you are just testing things out). Here is some reference:
How_to_package_your_game_with_commands

In my case, I am building the source as well as packaging for the server and client at the same time: this can be achieved using something like:

path_to_UE4_code\Engine\Build\BatchFiles\RunUAT.bat -ScriptsForProject=D:/pathtoproject.uproject BuildCookRun -nocompileeditor -nop4 -project=D:/pathtoproject.uproject -cook -stage -archive -archivedirectory=pathwhere toplacebuild -server -package -clientconfig=Development -serverconfig=Development -ue4exe=UE4Editor-Cmd.exe -prereqs -targetplatform=Win64 -build -CrashReporter -utf8output -compile

The server size went down from 700 MB of RAM to 110 MB + it loads up in less than a second.

Thanks for the help, that StipFlags put me on the right track.

1 Like