sehe
December 27th, 2013, 08:48 AM
Hi all,
After spending more than a week finding what leaks in Sapp (I even found and fixed some minor ones), it turned out that the mayor memory leak is in the dedicated server itself.
There are two allocations when a player joins, that doesn't get freed.
Once 480 byte leaks for sure, and another 5280 byte leak if the player stays for the next game.
With this 2 leaks, in a crowded server which is full 80% of the time, with short gametypes (~10 min each) a server can leak more than 10MB/day.
Here are the two allocations in Halo CE 1.09 dedi:
00474850 /$ 55 PUSH EBP
00474851 |. 8B2D 88D05400 MOV EBP,DWORD PTR DS:[<&KERNEL32.GlobalAlloc>]
00474857 |. 57 PUSH EDI
00474858 |. 68 A0140000 PUSH 14A0 ; /Size = 5280.
0047485D |. 6A 00 PUSH 0 ; |Flags = GMEM_FIXED
0047485F |. FFD5 CALL EBP ; \KERNEL32.GlobalAlloc
00474861 |. 8BF8 MOV EDI,EAX
00474863 |. 33C0 XOR EAX,EAX
00474865 |. 897E 14 MOV DWORD PTR DS:[ESI+14],EDI
00474868 |. 68 E0010000 PUSH 1E0 ; /Size = 480.
0047486D |. B9 28050000 MOV ECX,528 ; |
00474872 |. F3:AB REP STOS DWORD PTR ES:[EDI] ; |
00474874 |. 8B7E 14 MOV EDI,DWORD PTR DS:[ESI+14] ; |
00474877 |. 50 PUSH EAX ; |Flags => GMEM_FIXED
00474878 |. FFD5 CALL EBP ; \KERNEL32.GlobalAlloc
0047487A |. 8946 08 MOV DWORD PTR DS:[ESI+8],EAX
0047487D |. C700 00000000 MOV DWORD PTR DS:[EAX],0
00474883 |. 8BCF MOV ECX,EDI
00474885 |. 5F POP EDI
And where the 5280 bytes gets freed when a player quits (not when a new game starts tho):
0046E482 |. 8B0D E0555F00 MOV ECX,DWORD PTR DS:[5F55E0] ; ASCII "update server queues"
0046E488 |. 6BFF 64 IMUL EDI,EDI,64
0046E48B |. 8B51 34 MOV EDX,DWORD PTR DS:[ECX+34]
0046E48E |. 8B4417 3C MOV EAX,DWORD PTR DS:[EDX+EDI+3C]
0046E492 |. 8D7C17 28 LEA EDI,[EDX+EDI+28]
0046E496 |. 50 PUSH EAX ; /hMem
0046E497 |. FF15 94D05400 CALL DWORD PTR DS:[<&KERNEL32.GlobalFree>] ; \KERNEL32.GlobalFree
0046E49D |. C747 14 00000000 MOV DWORD PTR DS:[EDI+14],0
I fixed both with freeing them when a player leaves and when a game ends.
I just wonder how no-one realized this for almost 10 years :shake:.
After spending more than a week finding what leaks in Sapp (I even found and fixed some minor ones), it turned out that the mayor memory leak is in the dedicated server itself.
There are two allocations when a player joins, that doesn't get freed.
Once 480 byte leaks for sure, and another 5280 byte leak if the player stays for the next game.
With this 2 leaks, in a crowded server which is full 80% of the time, with short gametypes (~10 min each) a server can leak more than 10MB/day.
Here are the two allocations in Halo CE 1.09 dedi:
00474850 /$ 55 PUSH EBP
00474851 |. 8B2D 88D05400 MOV EBP,DWORD PTR DS:[<&KERNEL32.GlobalAlloc>]
00474857 |. 57 PUSH EDI
00474858 |. 68 A0140000 PUSH 14A0 ; /Size = 5280.
0047485D |. 6A 00 PUSH 0 ; |Flags = GMEM_FIXED
0047485F |. FFD5 CALL EBP ; \KERNEL32.GlobalAlloc
00474861 |. 8BF8 MOV EDI,EAX
00474863 |. 33C0 XOR EAX,EAX
00474865 |. 897E 14 MOV DWORD PTR DS:[ESI+14],EDI
00474868 |. 68 E0010000 PUSH 1E0 ; /Size = 480.
0047486D |. B9 28050000 MOV ECX,528 ; |
00474872 |. F3:AB REP STOS DWORD PTR ES:[EDI] ; |
00474874 |. 8B7E 14 MOV EDI,DWORD PTR DS:[ESI+14] ; |
00474877 |. 50 PUSH EAX ; |Flags => GMEM_FIXED
00474878 |. FFD5 CALL EBP ; \KERNEL32.GlobalAlloc
0047487A |. 8946 08 MOV DWORD PTR DS:[ESI+8],EAX
0047487D |. C700 00000000 MOV DWORD PTR DS:[EAX],0
00474883 |. 8BCF MOV ECX,EDI
00474885 |. 5F POP EDI
And where the 5280 bytes gets freed when a player quits (not when a new game starts tho):
0046E482 |. 8B0D E0555F00 MOV ECX,DWORD PTR DS:[5F55E0] ; ASCII "update server queues"
0046E488 |. 6BFF 64 IMUL EDI,EDI,64
0046E48B |. 8B51 34 MOV EDX,DWORD PTR DS:[ECX+34]
0046E48E |. 8B4417 3C MOV EAX,DWORD PTR DS:[EDX+EDI+3C]
0046E492 |. 8D7C17 28 LEA EDI,[EDX+EDI+28]
0046E496 |. 50 PUSH EAX ; /hMem
0046E497 |. FF15 94D05400 CALL DWORD PTR DS:[<&KERNEL32.GlobalFree>] ; \KERNEL32.GlobalFree
0046E49D |. C747 14 00000000 MOV DWORD PTR DS:[EDI+14],0
I fixed both with freeing them when a player leaves and when a game ends.
I just wonder how no-one realized this for almost 10 years :shake:.