ByteArray memory allocations

Post here your questions about the Flash / Flex / Air API for SFS2X

Moderators: Lapo, Bax

geretti
Posts: 24
Joined: 01 May 2015, 07:02

ByteArray memory allocations

Postby geretti » 18 Sep 2015, 19:40

Hi there,

I'm going through my project optimizing memory and CPU usage. My largest memory allocations are now coming from SFS.

I've been noticing a high amount of memory allocations from the serialization engine. I'm attaching a screenshot from a :30 second session. It's a 60mb allocation for roughly 3kb/s worth of data (up&down).

Capture.PNG
(35.6 KiB) Not downloaded yet


I'm wondering if this part has been optimized at its best since I'm getting large garbage collections roughly every 30 seconds and it chokes the framerate.
Could you allocate a couple of megs for bytearrays and keep the allocation for the duration of the connection? That would be very helpful.

Grazie!
User avatar
Lapo
Site Admin
Posts: 23007
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: ByteArray memory allocations

Postby Lapo » 19 Sep 2015, 07:30

Hi,
we use the lowest amount possible of byte array objects, including some zero-copy practices at the low level. So yes indeed it has been optimized quite a lot.
In general the SFS2X memory footprint is really very low. In our 100K CCU benchmark (link) it used less than 3GB of RAM. Try that on a regular webserver! :D

EDIT:
I'm wondering if this part has been optimized at its best since I'm getting large garbage collections roughly every 30 seconds and it chokes the framerate.
Could you allocate a couple of megs for bytearrays and keep the allocation for the duration of the connection? That would be very helpful.

Oh wait... are we talking about client side?
Byte arrays are not resizable so it's quite difficult to reuse them. Any resizable implementation uses "new" behind the scenes...
What is your framerate and pps?
Lapo
--
gotoAndPlay()
...addicted to flash games
geretti
Posts: 24
Joined: 01 May 2015, 07:02

Re: ByteArray memory allocations

Postby geretti » 19 Sep 2015, 16:35

60fps,
20pps upload
20pps download

I need at least these rates to make the shooter work reliably :)
User avatar
Lapo
Site Admin
Posts: 23007
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: ByteArray memory allocations

Postby Lapo » 20 Sep 2015, 11:06

From the dark grey color of the UI in the screenshot I initially assumed it was Unity, but I now realize it is Flash.
Well, smooth 60fps + multiplayer in Flash seems like you're asking alot... :D But maybe you're using Stage3D?

In any case, it looks like you're incurring in some serialization overhead. Can you show me the structure of a client update packet? One of those 20 pps, I mean?
You may probably try to simplify the data so that it requires less serialization work.

Another idea is to reuse SFSObjects, instead of feeding the API new ones each time.
If you're sending positional updates such as:

Code: Select all

data.putFloat("x", 100.33);
data.putFloat("y", 81.705);
data.putFloat("x", 72.14);
data.putShort("rot", 45.5);
data.putShort("spd", 15);

You could avoid generating 20 new SFSObjects per second, and simply reuse the same object by overwriting the previous values.

Also as a simple test I profiled the generation of 600 of those SFSObjects (as in the snippet), the equivalent of 30 seconds @ 20pps.
The total amount of memory generated is roughly 160KB.

cheers
Lapo

--

gotoAndPlay()

...addicted to flash games
geretti
Posts: 24
Joined: 01 May 2015, 07:02

Re: ByteArray memory allocations

Postby geretti » 20 Sep 2015, 14:34

Here's a snippet:

var bytes:ByteArray = new ByteArray();
bytes.writeInt(_lastMasterStateTimestamp);
bytes.writeShort(int(_body.position.x));
bytes.writeShort(int(_body.position.y));
bytes.writeByte(NumberUtils.convertAngleToSignedByte(_angle));
bytes.writeByte(_bufferedInput.getValue());

var payload:SFSObject = new SFSObject();
payload.putByteArray(ServerParam.BYTEARRAY, bytes);

EventHub.dispatchEvent(new ServerEvent(ServerEvent.PLAYER_STATE, payload));
User avatar
Lapo
Site Admin
Posts: 23007
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: ByteArray memory allocations

Postby Lapo » 20 Sep 2015, 19:15

Well, although this doesn't explain it all... it is already clear that you are doubling the amount of work and memory (i.e. byte arrays).
Because first you create your own, and then you wrap it in the SFSObject which in turn will serialize the data into a new one.

I don't understand why you're manually serializing the data, while the same kind of work is already done by the SFS API, for you. Just add the data directly into the SFSObject maintaining the types that you're using (bytes, shorts, ints...). This will cut the memory and CPU work by 50% immediately.

cheers
Lapo

--

gotoAndPlay()

...addicted to flash games
geretti
Posts: 24
Joined: 01 May 2015, 07:02

Re: ByteArray memory allocations

Postby geretti » 21 Sep 2015, 17:57

My serialization is lighter because it doesn't pass keys, ever :) I used to use SFSObjects and Arrays for everything and they work great, but adding textstrings for all parameters got pretty heavy for high frequency, urgent UDP messages. My own serialization ligthened Tx/Rx by roughly 30%. It's not for everyone, I know, but I needed to create a snapshot-based netcode similar to the one from quake, and I was very familiar with SFS already so I used your engine.

Are you saying there will always be a duplicate bytearray created by SFS since it always serializes, even if it's a raw bytearray I'm passing to the API? Is there a way to bypass the serialization if I just wanted to pass a raw bytearray (which is almost always the case) ? Thank you
User avatar
Lapo
Site Admin
Posts: 23007
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: ByteArray memory allocations

Postby Lapo » 22 Sep 2015, 08:55

Naturally SFS must use its own byte array.
There is no way around it, not even using the most extreme and memory conservative approach.
If you're building a byte stream and you're given a bytearray you must have two byte arrays in memory: the stream which already exists and contains the header and other data and the external array that is being passed.

But I honestly think we're barking at wrong tree. I have no idea why you seem to observe 60MB of byte array data when my test shows 160KB for the same amount of packets.
As regards not using keys in SFSObjects, you can achieve the same by using an SFSArray which doesn't use any key and the wrap it in the SFSObject.


cheers
Lapo

--

gotoAndPlay()

...addicted to flash games

Return to “SFS2X ActionScript 3 API”

Who is online

Users browsing this forum: No registered users and 14 guests