GameMaker global arrays

jms

Member
Hi,

i was wondering if global arrays are just like global variables which dont get memory managed aka cleared, reason is to optimize memory management so i
wonder if there are any reason not to use global arrays.

using local variables and then have GM to handle memory management is from my point of view risky, why do it global variables should mean
GM dont need to do anything. or is the value size "a00" if its changed to larger like "a000000102301020301230" something problematic in detailed level i mean not practical.

reason i ask these is that i developed a software related to an invention back in the days having 1 million size array, each having 32 digits as a value, this took 1 gigabyte ram or more, for 32bit exe it was
somewhere a limit, also i read that max array 1d was 32 000 on the GM site, is that true or is it a recommendation.

manual
Description
With this function you can get the length (number of entries) of a 1D array. For 2D arrays you should be using the array_height_2d and array_length_2d functions.

WARNING!: If the array has over 32,000 entries this function will return an erroneous value and should not be used.


------------------

room1
//create event
global.arr1[0] = "a00"
global.arr1[1] = "a01"
global.arr1[2] = "a02"


room2
//draw gui event
draw_text(333,333,"global arr1:" + string(global.arr1[0] ) )
 

jms

Member
MAX number of array elements in GM 64bit? what is that?
.NET, C, Java, Delphi etc they have some limits regarding number of array elements and by design they dont care about if the value is a number string or byte and the length which ofcourse in pratical sense takes more RAM, but anyway someone from YOYO is there a possibility to adjust the MAX nr of array elements to > 1million or more like 1 billion or is it done already??
 
Last edited:

rytan451

Member
Global arrays are arrays that happen to be stored in a global variable. They're managed in the same ways as other arrays, in that if they lose all incoming references, they eventually are cleared by the GC.

Why not use global arrays? Well, a global array needs a global variable. So, if you want an instance of an object to have its own array, using a global array means that it shares that one array with other instances, which is bad.

What exactly do you mean by this sentence:

using local variables and then have GM to handle memory management is from my point of view risky, why do it global variables should mean GM dont need to do anything.
What exactly do you mean by this sentence:

or is the value size "a00" if its changed to larger like "a000000102301020301230" something problematic in detailed level i mean not practical.
Yes, having a large array will tax RAM usage. Computers running a 32 bit OS cannot utilize more than 4 GB of memory, which is approximately 1 billion doubles (numbers in GMS). If you're storing 3 character long strings, that's 4 bytes for the pointer to the string, 3 bytes for the string itself, and 1 byte for the null termination character, and more bytes for GMS's overhead. That means that you can only have 250 million 3-character strings as a theoretical maximum. In practice, you're not going to reach that far, since GMS has loads of overhead, and there's going to be lots of memory already used up by the time your program starts.

Since numbers in GMS are double precision floating point numbers, you can only represent every integer up to 2^53 (about 9 quadrillion). This is a technical limit, since for numbers above 2^53, only even numbers can be represented. However, the actual limit is probably how much RAM the OS is willing to allocate to the game, which is much smaller. For scale, 2^53 bytes is more than 2 petabytes, (more than 2,000 terabytes).

The limit on 32000 isn't mentioned in latest version of the documentation. Are you using the newest version of GMS?
 

Nidoking

Member
Global arrays are arrays that happen to be stored in a global variable. They're managed in the same ways as other arrays, in that if they lose all incoming references, they eventually are cleared by the GC.
It's impossible for a global variable to lose all references, because it's global. Anything can refer to it at any time.
 

FrostyCat

Redemption Seeker
It's impossible for a global variable to lose all references, because it's global. Anything can refer to it at any time.
The original poster is talking about arrays in global variables, which can lose all references if the global variable holds the only reference and it is set away to something else.

Besides, starting with GMS 2.3.1, you can delete global variables with variable_struct_delete(global, "variableName").
This is true...although you could assign a single number or string to it, which would remove the array it had before. That's one of the quirks of dynamic typing.... I'd never do that, but it is a thing.
It would remove the array only if the reference to it isn't saved anywhere else. For example, if an instance runs this:
GML:
myArray = global.theArray;
global.theArray = undefined;
The array would still be alive as long as the instance is (through myArray), even though global.theArray has been set back to scalar.

The main problem with the original poster is that he's still thinking of arrays as a variable type like in legacy GM, instead of as a first-order value type like in modern GMS.
 

kburkhart84

Firehammer Games
It would remove the array only if the reference to it isn't saved anywhere else. For example, if an instance runs this:
This is true...I just assumed they didn't do that as I described it as only the changing of the original variable without any additional code.

The main problem with the original poster is that he's still thinking of arrays as a variable type like in legacy GM, instead of as a first-order value type like in modern GMS.
Gotta get with the times people!! :)
 

TheouAegis

Member
Did 2.3 fix the array structure, though? As of 2.2, it still had a 32k limit, but changed the 32k hard limit to a soft limit, meaning any array with more than 32k elements was actually comprised of n arrays, where n was the highest index mod 32k.
 

jms

Member
//create event


GML:
for (i=0; i < 31000; i++){
global.test[i]=i   
}

//draw_gui event

draw_text(64,64,string(array_length_1d(global.test)))

it reports 32000
i am on 2.2.5

1. the array is created in init_room and it stay in the ram just like global.variables
2. you can change the value whenever you want etc do sorting. the array stays forever only the value is changed if you change it
3, variable and arrays values are meant to changed, such as switching a language strings value in an array
 
Last edited:

GMWolf

aka fel666
The variable does not hold the array. It holds a reference to the array.
So even though the global variable will always persist, the array it refers to could get freed if, for example , the variable is assigned to something else.

The variable != the array.
 

jms

Member
The variable does not hold the array. It holds a reference to the array.
So even though the global variable will always persist, the array it refers to could get freed if, for example , the variable is assigned to something else.

The variable != the array.
i wrote software for 10 years ago having gui components and menus to switch 25 different languages, 186 some global variables read from ini then assigned to global.word1 = ini pos 1 etc
yes the reference but either having 30000 global variables or an global variable refering to an array, if you want switch from eng to spanish forexample 30000 different words and then change the word from "house" to "casa". house being array position 999.
Code:
global.test[999]= "casa"
 

FrostyCat

Redemption Seeker
Can you please STOP making conclusions based on outdated versions of GM and outdated documentation?

GMS 2.2.5 was released more than 1 year ago in December 2019. We are now on GMS 2.3.1, and a major update to GML happened in August 2020 with GMS 2.3.0.

You cited the 32000 limit from docs.yoyogames.com, which is the Manual for GMS 1.4.9999, not for GMS 2.2.5 (docs2.yoyogames.com) and certainly not for GMS 2.3.1 (manual.yoyogames.com). Even when you did cite the GMS 2.3.1 manual, it's from a page clearly marked as deprecated. The only hard limit now is the size of the addressing space (2GB for 32-bit, 16EB for 64-bit) or the amount of available RAM on the system, whichever is smaller. The number of entries doesn't matter, only the combined size of everything in the array.

Running this on GMS 2.3.1.542 gives 33000 as expected, well above the old 32000 limit:
GML:
for (var i = 0; i < 33000; ++i) {
    global.test[i] = i;
}
show_message(array_length(global.test));
Your arguments about the limitations of arrays are no longer valid.
 

jms

Member
i looked at the manual for GMS 2 and it was a simple question, now i know since you tested it on 2.3.1 that great, reason why i dont go with the 2.3.1 is that it totally broke my projects.
 

GMWolf

aka fel666
i wrote software for 10 years ago having gui components and menus to switch 25 different languages, 186 some global variables read from ini then assigned to global.word1 = ini pos 1 etc
yes the reference but either having 30000 global variables or an global variable refering to an array, if you want switch from eng to spanish forexample 30000 different words and then change the word from "house" to "casa". house being array position 999.
Code:
global.test[999]= "casa"
I don't understand. Is this a question? A statement? I really don't follow.
 

TheouAegis

Member
for (i=0; i < 31000; i++){ global.test=i }
Don't create arrays going up, create them starting with the highest index. It has to allocate increasing amounts of memory when you start with a low index and count up. If you start with the highest index, it will allocate all the memory at once. For small arrays, you will never notice the difference, but very, very large arrays will be more apparent.
 
  • Like
Reactions: jms
Top