Advertisement

[Java] How "System Intensive" Would This Be ?

Started by February 07, 2014 10:01 PM
10 comments, last by RLS0812 10 years, 7 months ago

I am wondering how much of a strain this scenario would put on a server:

An object 2D array[100][100] that is populated by objects that are 2d array[50][50] - which is populated by an array String[6].

What this does is simulate map chunks that are loaded as the player moves around.

The first 2D array is the world.

The Object 2D array is each map zone.

The String array is each tile.

The world it's self is procedurally generated.

I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

I'm working on a multiplayer isometric game, and for fun I thought I would try and load the entire map (about 1 million or so tiles) and draw them all on the screen, which without any optimizations ran at around 4 frames per second. Assuming you aren't fetching the whole map 60 times per second, you should be fine.

Stay gold, Pony Boy.
Advertisement

Only the "chunks" that are rendered on the player's screen .

I believe this method would be more efficient than loading the whole map into memory.

I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

I am wondering how much of a strain this scenario would put on a server:

An object 2D array[100][100] that is populated by objects that are 2d array[50][50] - which is populated by an array String[6].

Not much strain, but I'd probably arrange it slightly differently.

A 2D array is really just a 1D array with a stride, so you have 10,000 objects in the first array. Each of those objects are 2,500 entry objects, each 6 bytes.

So 6 bytes * 2500 * 10000 = 150 megabytes, give or take.

So rather than allocating 25000000 objects, I'd make a single really big character array, or maybe a small number of medium-sized arrays. That avoids having 150 million constructor calls, 150 million allocations, 150 million memory management tasks, and so on.

You can fit that on any modern PC's memory no problem, you can even stick that entirely in a modern video card if you want to do some GPGPU-style processing.


Probably much more important: What do you intend to do with that 150MB of data?

Simple lookup of data is probably nothing too serious. Straight linear processing of various segments wouldn't be bad because of cache effects. If you intend to process and modify data in each of the 25000000 six-byte buffers on a rapid basis, you will probably want to find some ways to parallelize the work, but if the work was light even that can be done on a fast modern server-grade machine with fast memory.

Most of that is a map file.

the simple String array is what would hold the information for each map tile which would include: interaction items, players, enemies, "loot" piles, switches, and zones.

The second 2D array is the tile map with the references to the textures.

The first 2D array is what stores all the tile maps into "chunks" .

Well - at least that is my solution to dynamically loading a 2D map as the player moves along.

I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

As this is Java, note that what you described is something Java is particularly poor at handling.

Every object you create is going to need to be constructed, and eventually garbage collected.

Each of your map segments is going to have all those objects, and the net result is going to be what? Around 50,000 constructors called? Also String is a special beast, are you sure you want to use those instead of byte arrays?

Even worse, if your memory pools are already dirty this could require some serious work. Doing 50,000 individual allocations for a single zone might trigger the GC to run several times or even cause the VM to grow the memory pool. Trust me, the player is going to notice that as they are blissfully moving along and suddenly the app stalls.

Much worse if you attempt the full 150MB collection of stuff, you are looking at millions of constructor calls. I can only guess at the state of your memory pools, especially as these are long-term allocations that will slowly be moved over into the older generation pools, and (shudder) get garbage collected. There is nothing speedy about that.

I can imagine wanting to warn your users about that: "Please wait. The JVM is now cross-checking over 20,000,000 allocations to see if any of them are dead. In the mean time, please go make a sandwich."

Coalesce your data. Make a small number of very large objects rather than millions of tiny objects.

Advertisement

I wish I could .. somehow ... Java does not allow me to make a 2D array of other 2D arrays.

This should be named "array-acception" !

String array, inside of a 2D array inside of another 2D array !

I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

I wish I could .. somehow ... Java does not allow me to make a 2D array of other 2D arrays.

This should be named "array-acception" !

String array, inside of a 2D array inside of another 2D array !

I'd recommend looking into the good old sun.java.Unsafe class. it is not officially documented and you can't create an instance of it directly but it allows you to deal with memory manually and can be a huge help when writing performance critical code in Java (You have to use reflection to access it but once you got an instance of the Unsafe object you can make direct memory allocations and can treat long values as pointers and a whole bunch of other neat tricks.

Memory allocated through the Unsafe class will not be cleaned up by the GC either.

[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

Do you need to load up all the "zones" at once? I would assume a player can only be at one zone at a time, meaning you should only care about loading one [50][50] array (which I'd recomment to collapse it into a 1D array of 2500). Then you can use some sort of tree structure to determine the neighboring zones when player navigate from one to another.

Many games have dynamically loading open world maps, which I would love to emulate.

The map I am working on is only 5,000 * 5,000 tiles in size, however I do not think it would be beneficial to load the whole think onto the player's screen at once time.

The string array would be the only item loaded from the server side, since it would have the vital game data, everything else would be the map file.

I could have a "buffer" of 9 "chunks" loaded around the player ( 3 X 3 chunks ) and load chunks off screen - however I am at a bit of a loss on how to do that.

A chunk would be 50 x 50 tiles ( 800 x 800 pixels )

I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

This topic is closed to new replies.

Advertisement