Memory leak with display_title for header and footer? (HUDController)
replaceitem opened this issue · 4 comments
I have a script on my server that continuously (every tick) updates the player list header and footer, and the server reaches memory limit (in my case 8gb) within a couple hours.
Carpet version: 1.17-1.4.40-v210608
I managed to get a heap dump file (.hprop) from the server with all memory being used.
It confirmed that the HUDController is using 52% of memory. Here is a screenshot of it opened in eclipse memory analyzer:
I could upload the heap dump file somewhere, but its 6gb, so if that would help debugging i could do that.
I tried spotting the cause myself, but im not an expert in memory stuff so i wasn't successfull.
Here is the script that most likely is causing it:
__config() -> (
m(l('stay_loaded', true),l('scope', 'global'))
);
global_evmotd = format('#00CCFF ════════▶ ');
global_evmotd += format('b#91F78C East');
global_evmotd += format('b#45C142 Valley ');
global_evmotd += format('#FFFF00 - ');
global_evmotd += format('#FF4400 1.17 ');
global_evmotd += format('#CC33FF SMP');
__on_tick() -> (
if(tick_time() % 40 == 0,
motd = global_evmotd;
motd += '\n';
motd += reduce(map(sort_key(player('all'),_~'player_type'=='fake'),_~'display_name'),_a += _ + ' ',format(' '));
set_motd(motd);
);
if(tick_time() % 4 == 0,
ticksum = 0;
for(last_tick_times(),
ticksum += _;
);
global_mspt = ticksum / length(last_tick_times());
);
if((tick_time() % 1) == 0,
headerHue = tick_time()%360;
headerGlossIndex = (floor(time()/60)%40)-10;
header = [];
header += ' \n';
title = 'EastValley';
title = split(title);
for(title,
if(abs(_i-headerGlossIndex) < 3,
c = '#' + convert_color([headerHue,abs(_i-headerGlossIndex)/3*255,255],'hsb','hex');
,
if(_i < 4,
c = '#' + convert_color([headerHue,255,190],'hsb','hex');
,
c = '#' + convert_color([headerHue,255,255],'hsb','hex');
);
);
put(header,null,str('b%s %s',c,_));
);
header += ' \n';
header = format(header);
//CALCULATE MSPT
hue = constrain(map_num(global_mspt,0,100,180,0),0,180);
c = 0;
for(player('all'),
c+=(_~'player_type'!='fake');
);
footer = format(str('#44FF44 MSPT: '));
footer += format(str('%s %.2f','#' + convert_color([hue,255,255],'hsb','hex'),global_mspt));
maxmem = system_info('java_max_memory');
mem = system_info('java_used_memory');
hue = constrain(map_num(mem,0,maxmem,180,0),0,180);
footer += format('#44FF44 \nMEM: ');
footer += format(str('%s %.2fgb','#' + convert_color([hue,255,255],'hsb','hex'),mem*0.000000001));
cpu = system_info('java_system_cpu_load');
footer += format('#44FF44 \nCPU: ');
hue = constrain(map_num(cpu,0,1,180,0),0,180);
footer += format(str('%s %.2f%%','#' + convert_color([hue,255,255],'hsb','hex'),cpu*100));
display_title(player('all'),'player_list_header',header);
display_title(player('all'),'player_list_footer',footer);
)
);
map_num(value,start1,stop1,start2,stop2) -> start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
constrain(v,a,b) -> (
min = min(a,b);
max = max(a,b);
max(min,min(v,max));
);
Is it possible that couple hundred player show up and loggs out in that timeframe?
Oh yeah, convert_color is from my extension.
And there are maybe max 15 different players online in that time.
Thanks for fixing!
Could also use a WeakHashMap
for better performance (?) given that is ticked, in case it becomes a bottleneck at some point (and would be a bit simpler I guess), though the way you changed seems like it shouldn't cause any.
Sorry about that, totally forgot that players don't share the same instance after reconnecting.