multitheftauto / mtasa-blue

Multi Theft Auto is a game engine that incorporates an extendable network play element into a proprietary commercial single-player game.
https://multitheftauto.com
GNU General Public License v3.0
1.42k stars 438 forks source link

callRemote and fetchRemote are inefficient #398

Open ArranTuna opened 6 years ago

ArranTuna commented 6 years ago

Describe the bug If a server uses callRemote a lot, it seems that the memory it uses doesn't get freed up after waiting a long time.

To Reproduce Steps to reproduce the behavior:

  1. Add <min_mta_version server="1.3.1"></min_mta_version> to your runcode meta.xml
  2. Start local server
  3. Start runcode
  4. Open task manager and check current usage of MTA server.exe
  5. Paste run for i=1, 10000 do callRemote("a", 1, function() end) end into server console and hit enter
  6. Observe memory usage goes up to about 350mb where it then stays and doesn't go back down

MTA Client/Server (please complete the following information):

Occurs in 1.4 Occurs still in 1.5.9 r20955 both 32 and 64 bit server

Additional context From https://bugs.mtasa.com/view.php?id=7565

qaisjp commented 6 years ago

@Audifire said:

Today I had time to test your code and I analyzed the problem.

So I degugged the callRemote procedure and the I got the following result:

If you call the callRemote function every time there will be created a CRemoteCall object in the C++ source code. Every of this objects are getting in a queue from downloading manager. Now when you create 100000 of the objects and the queue need to work off all this objects.

After a work off of one object the object will be deleted and the memory will be free. But here you see the speed of the work off: http://www.audifire.de/mtasa/images/workoff.png

So the code works well, but the demonstrated code example is very inefficient.

In the afternoon I will test this with a valid test result. The problem is, every RemoteCall will take about 3 seconds.

Now: 100000 * 3 seconds = 300000 seconds 300000 seconds / 60 seconds per minute = 5000 minutes 5000 minutes / 60 minutes per hour = 83.3 hours 83.3 hours / 24 hours per day = 3.47 days

The result to workoff are 3.47 days, then the memory will largely be free. :D Another problem is, that the result length is not always the same (~ 3 seconds).

@castillo14 said:

fetchRemote seems to be also affected by this, a resource using fetchRemote often will freeze the server if you restart it after a while (a day or so).