Innula Zenovka Posted July 30, 2012 Share Posted July 30, 2012 Maybe I'm the only one who didn't realise this, but people should be aware that llGetAgentList can be dangerous in some circumstances.It returns up to 100 keys, and there's no way of limiting this. And, as Haravikk Mistral, who started a jira about it (SRC-371), comments: while it's incredibly unlikely, if the function is able to return potentially 100 results than that's at least 6kb of memory, far more likely ~10kb with list overhead, which means you need 20kb (30kb to be safe) to actually manipulate such a list…I came across it while I was planning out a script for an attachment which, since the script does a lot of other things too, would probably have blown up if it detected more than ~30 people on the sim, and that's obviously a more realistic danger.There's some discussion, and background, over at SLU. Link to comment Share on other sites More sharing options...
Talia Davidov Posted July 30, 2012 Share Posted July 30, 2012 That had not occurred to me either, and I just released updates to my entire product line with scripts that use it. I tested with 25 people on the sim, but the implication of what happens in an even busier place did not occur to me. Thanks for the heads up. ETA: I got lucky, the script I have calling it has quite a bit of free memory. Link to comment Share on other sites More sharing options...
Freya Mokusei Posted July 30, 2012 Share Posted July 30, 2012 My process (accidentally) for using llGetAgentList so far has to been to test with llGetAgentCount to start (if the sim has more than 20 avs, llGetAgentList doesn't fire). Mostly because the purpose I needed it for, I only need those numbers if the sim is on the quiet side. If you absolutely needed a list, I guess you could go 'old-school' and run a sensor instead. Too cludgy? Does kind of undermine the purpose of the new commands. Link to comment Share on other sites More sharing options...
Miranda Umino Posted July 31, 2012 Share Posted July 31, 2012 Wrong problem : firstly 10kb is few when your script is limited to 64kb secondly there is absolutely no reason tu compile new scripts with new functons in LSO thirstly you are not obliged to keep the 10kb . You need them only when you parse the answer of llgetagentlist . So the memory will be freed after the next event . Save only the keys who interest you. fourthly there are other finctions as http://wiki.secondlife.com/wiki/LlGetParcelPrimOwners who may return 100 values . In fact , its a strided list , so llGetParcelPrimOwners may return 100 keys and 100 integers , so 1.5 X more than llGetAgentList . Nobody has complained about this . Nobody has requested about llGetParcelPrimOwners to limit the size of returned datas. And its more frequent in-world to have 100 different prim-owners in a sim ( for instance in a sandbox , or in a group ) . To have 100 avatars in a sim is less frequent llCastray may return a strided list of 256 elements , so , with additional flags 256 keys , 256 postion vectors , 256 integer , and 256 normal vectors . It s s something around 40kb llGetLinkPrimitiveParams may return more than 10kb if you call as llGetLinkPrimitiveParams(LINK_THIS,, [options, PRIM_LINK_TARGET , link2, option2, PRIM_LINK_TARGET, link3, options3 .. PRIM_LINK_TARGET,link255, option255] ) with a 256 prim linked Only with 4 prims a call as l = llGetLinkPrimitiveParams(LINK_THIS, [ PRIM_TEXTURE, ALL_SIDES, PRIM_LINK_TARGET , 2, PRIM_TEXTURE, ALL_SIDES, PRIM_LINK_TARGET , 3, PRIM_TEXTURE, ALL_SIDES, PRIM_LINK_TARGET , 4, PRIM_TEXTURE, ALL_SIDES] ); may take 10kb . It depends of the number of faces of your prims ( sphere with one face or mesh / tortured torus with 8 faces) Firthly , you have some additional filters to llgetegentlist to limit to a parcel . How many sims have 100 avatars on . And how many parcels have 100 avatars on ? I don t see a lot of them in-world To forbid and to limit scripters are bad . This limitation to 20 is not meaningful : Which avatars will be returned ? The nearest of the prim ? It s long and costly for the sim . The fisrtsly laphabetically named agents ? Some random keys ? It s useless for the scripter to have 20 random agents in the region. And more stupid if you want to limit to 20 the results of llGetAgentList is the absence of pagination. Something like list llGetAgentList( integer scope, list options, integer page ); Why to have some keys about a subset of agents , when there is no rule to determine this subset , and there is no way to switch from a subset to an another subset ? I don t see any interest But even if some pagination would exist , the datas won t be coherent : if Linden Lab adds some pagination to this function , how will be coherent the datas returned between the call for the first page and the call of the second page if people enter and leave in the sim between the two moments ? Link to comment Share on other sites More sharing options...
Innula Zenovka Posted July 31, 2012 Author Share Posted July 31, 2012 All I was saying, Miranda, is that when you use llGetAgentList there are circumstances in which it's going to use quite a considerable amount of memory -- potentially a lot more than would llSensor, which I was using it as a replacement for -- and it's as well to be aware of this. Of course I'm not saying don't use it -- all I'm saying is that if you're using it in a long and complicated script that's storing other things as well, which is the case with the script I'm working on, it's good to keep in mind that you may find yourself briefly manipulating a much longer list than you might have been expecting, or than you've encountered in testing. That's all. Link to comment Share on other sites More sharing options...
Talia Davidov Posted July 31, 2012 Share Posted July 31, 2012 Innula's observation and warning were much appreciated by me. We should never plan our scripts on the best case scenario. There is very little chance of a sim with 100 Avatars. It is still theoretically POSSIBLE, and therefore we need to take it into consideration in our memory usage planning. As for the rest of the discussion about other functions returning a great deal of data . . .um . .so? You need to plan for them too if you use those functions. Link to comment Share on other sites More sharing options...
Miranda Umino Posted July 31, 2012 Share Posted July 31, 2012 Nevertheless the solution told by this JIRA is not a solution ... Neither exact , neither satistfying The "solution" doesnt solve some memory issues caused by other functions llGetParcelPrimOwners, llCastray , llGetLinkPrimitiveParams and in a general way , every functions returning a list The "solution" doesn t give a way to have some exploitable, functionnal , useful datas . What could i do with 20 random keys of agents present in my sim if there are 100 agents ? For instance , if i want to use llgetagentlist to check who are the agents in my sim who meet a particular criteria , how could i do it with a truncated list ? How i do for instance to know all the avatars with an agentsize below of 1m , if the list returened by llgetagentlist is truncated ? Second instance , this function has been required , for instance to check who has entered in a sim and who has left : how could i know it with a truncated list ? Of course , i agree to secure our scripts . But this solution is not helpful. If it was possible to use some callbacks of user defeined functions it would be nicer. For instance , with a callback who returns always a boolean , and have the key of agent in parameter integer mycallback_has_no_display_name( key avatar){ string name = llGetDisplayName(avatar); if ((name == "???") || (name == "")) return TRUE; else return FALSE;}llRegisterCallback("mycallback_has_no_display_name");list results = llGetAgentList(AGENT_LIST_REGION, "mycallback_has_no_display_name" );And internally llgetagentlist applies our callback for each element of the list . The list "results" could contain only the avatar with no display names. Link to comment Share on other sites More sharing options...
Ela Talaj Posted July 31, 2012 Share Posted July 31, 2012 100 keys take 3600 bytes (100x36), with list overhead prolly would take 5K. An efficient script would need about 10K for processing, no more than that. If don't have 10K available, make another module that would do only large list storage/processing and talk to the main script via linked msgs. Link to comment Share on other sites More sharing options...
Innula Zenovka Posted July 31, 2012 Author Share Posted July 31, 2012 I agree the jira solution isn't a particularly good one since, as you say, there's little point in truncating the list unless you can specify to the sim how you want it ordered. If that were possible, it would be great -- tell me the 30 nearest avatars, or tell me the 10 avatars who've been here longest -- but that looks easier said than done. I just quoted the jira because it explained why the long lists are problem. Which, under some circumstances, they certainly are, if you 're not expecting them. Link to comment Share on other sites More sharing options...
Miranda Umino Posted July 31, 2012 Share Posted July 31, 2012 Maybe you may try llList2List before to store the result of llgetagentlist in a variable . Logically you will have more than 64kb but maybe it doesn t give the time to the memory manager to crash your script . Probably it s very unsafe . I remember may times some scripts crashing when we use as it I am just giving this instance of script , but i don t hint it . It s not a solution list keys;list dummy;integer half;default{ link_message(integer sender, integer num, string s, key k) { if ( num == 1000 ) { llOwnerSay("======= 1st Half ========"); llScriptProfiler(PROFILE_SCRIPT_MEMORY); llOwnerSay("before="+(string)llGetUsedMemory()); half = llGetRegionAgentCount() / 2; keys = llList2List( llGetAgentList(AGENT_LIST_REGION, []) , 1, half ); llOwnerSay("after="+(string)llGetUsedMemory()); llOwnerSay((string)llGetListLength(keys)+ " keys"); llScriptProfiler(PROFILE_NONE); llOwnerSay("This script used at most " + (string)llGetSPMaxMemory() + " bytes of memory .") ; keys = []; llMessageLinked(LINK_THIS, 1001, "", "" ); } else if ( num == 1001 ) { llOwnerSay("======= 2nd Half ========"); llScriptProfiler(PROFILE_SCRIPT_MEMORY); llOwnerSay("before="+(string)llGetUsedMemory()); half = llGetRegionAgentCount() / 2; keys = llList2List( llGetAgentList(AGENT_LIST_REGION, []) , half + 1, -1); llOwnerSay("after="+(string)llGetUsedMemory()); llOwnerSay((string)llGetListLength(keys)+ " keys"); llScriptProfiler(PROFILE_NONE); llOwnerSay("This script used at most " + (string)llGetSPMaxMemory() + " bytes of memory .") ; keys = []; llMessageLinked(LINK_THIS, 1002, "", "" ); } else if ( num == 1002 ) { llOwnerSay("======= Full ========"); llScriptProfiler(PROFILE_SCRIPT_MEMORY); llOwnerSay("before="+(string)llGetUsedMemory()); keys = llList2List( llGetAgentList(AGENT_LIST_REGION, []) , 1, -1 ); llOwnerSay("after="+(string)llGetUsedMemory()); llOwnerSay((string)llGetListLength(keys)+ " keys"); llScriptProfiler(PROFILE_NONE); llOwnerSay("This script used at most " + (string)llGetSPMaxMemory() + " bytes of memory .") ; keys = []; } } touch_end(integer n) { llMessageLinked(LINK_THIS, 1000, "", "" ); }} WIth a 70 avtars sims : sometimes it s ok : [11:50] Object: ======= 1st Half ========[11:50] Object: before=7036[11:50] Object: after=11220[11:50] Object: 39 keys[11:50] Object: This script used at most 11220 bytes of memory .[11:50] Object: ======= 2nd Half ========[11:50] Object: before=7036[11:50] Object: after=11016[11:50] Object: 38 keys[11:50] Object: This script used at most 11086 bytes of memory .[11:50] Object: ======= Full ========[11:50] Object: before=7036[11:50] Object: after=15200[11:50] Object: 77 keys[11:50] Object: This script used at most 15200 bytes of memory . sometimes it s dnagerous [11:51] Object: ======= 1st Half ========[11:51] Object: before=7036[11:51] Object: after=11310[11:51] Object: 41 keys[11:51] Object: This script used at most 11380 bytes of memory .[11:51] Object: ======= 2nd Half ========[11:51] Object: before=7036[11:51] Object: after=15660[11:51] Object: 39 keys[11:51] Object: This script used at most 15660 bytes of memory .[11:51] Object: ======= Full ========[11:51] Object: before=7036[11:51] Object: after=15388[11:51] Object: 80 keys[11:51] Object: This script used at most 15458 bytes of memory . It seems be important to leave the event or to wait a few moment between 2 calls two llgetagentlist to have the memory freed Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now