mIRC Home    About    Download    Register    News    Help

Print Thread
memory allocation limit on binvar #270142 09/04/22 08:43 PM
Joined: Jul 2006
Posts: 3,880
W
Wims Offline OP
Hoopy frood
OP Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 3,880
On mIRC 6.35, "/bset &a N 0" can be used to set a much longer binvar of N bytes than the current version.

On the current version 7.68, with mIRC already using 38KB, I can 'only' get N to represent 650MB or so, on 6.35 it would be around 1.3GB.

In addition, if you find a maximum value for N that you can pass to /bset at a given time, where N+1 would fail with an error, you can in fact create a second binvar with data in it, making the first limit on the binvar uncalled for.

I don't really have a script to demonstrate this because finding the maximum N is not trivial with a script if you make it starting at 1 and increasing by 1 until it fails. Well it can take a long time, here is something I used that worked quickly for me at some point, this script can be edited to increase (and decrease) %a in the first loop by a larger number the same way the decreasing second loop is, that will give you an incorrect first maximum, but it should still illustrate that a second binvar can be created, large enough to cover the gap of the maximum of the first binvar + at least one byte more.

Note: the code is on one line because of this report: https://forums.mirc.com/ubbthreads.php/topics/270141/

Code
//var %a 440000000,%b %a | while (1) { bset &error %a 0 | inc %a } | :error | reseterror | dec %a | bunset &error | echo -ag first current max %a | bset &1 %a 0 | var %a %b | :goto | while (1) { bset &error %a 0 | echo second max %a -- echo -ag $bvar(&1,0) + $bvar(&error,0) | return } | :error | var %error $error | reseterror | if (%error) { bunset &error | dec %a 10000 | goto goto }
This code use the fact that /bset will fail to set a too large binvar, we catch the error and the maximum value it can set, we set a binvar to that size, then we assume setting a second one of that size will fail so we do a decreasing loop from the original N we tried first.

What is the reason for such a big difference compared to 6.35? Why is there some rather very low arbitrary limit for /bset when once its limit reached, a second binvar of a rather large size can still be created? Is this a regression, if not could it be improved?

Re: memory allocation limit on binvar [Re: Wims] #270152 11/04/22 09:43 AM
Joined: Dec 2002
Posts: 5,104
Khaled Offline
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,104
Right. This is not actually related to v6.35; the difference is present between v7.52 and v7.53. There were some major changes between v7.52 and v7.53, the most important of which was increasing maximum string length, which is something that had been requested for a long time. This in turn required increasing the reserve stack size from 2MB to 8MB.

It is the reserve stack size that is causing this.

I just realized that I was misreading the results from your script. I have just run your script again, changing the /inc amount to 1MB per loop. When I run the script under v6.35 and v7.68 here, the difference in memory allocation is literally the stack size. So I am not seeing your results.

I also compared the /bset code from v6.35 to v7.68 and they are doing the same thing: malloc() and then realloc(). There is practically no difference in the code. I tested this in a simple C application that just does malloc()/realloc() and saw the same results.

So my guess is that this is down to how much memory is being allocated, how the C malloc() library is managing the memory, and so on, before your script runs. In this case, if mIRC is making thousands of calls, which it does, to allocate memory for various features, and you then attempt to allocate the largest possible chunk of memory, the current memory usage will affect that.