Hi,
I have written a small program called nginwho for my company that parses nginx logs and stores them in a database. Here is the link to the repo:
https://github.com/pouriyajamshidi/nginwho
The program is compiled using -d:release --mm:orc --threads:off flags and Nim version 2.0.2:
> nim --version
Nim Compiler Version 2.0.2 [Linux: amd64]
Compiled at 2023-12-15
Copyright (c) 2006-2023 by Andreas Rumpf
git hash: c4c44d10df8a14204a75c34e499def200589cb7c
active boot switches: -d:release
While monitoring the process on one of our servers (and then others), we noticed it is consuming 100MB memory which seemed not right. So, I wrote a Bash script to continuously monitor the memory usage of this process and noticed this recurring pattern:
2024-03-05 18:13:13 -> 1 MB
2024-03-05 18:13:18 -> 2 MB
2024-03-05 18:13:28 -> 4 MB
2024-03-05 18:14:59 -> 5 MB
2024-03-05 18:16:49 -> 6 MB
2024-03-05 18:18:29 -> 7 MB
2024-03-05 18:19:49 -> 8 MB
2024-03-05 18:21:29 -> 9 MB
2024-03-05 21:17:17 -> 10 MB
2024-03-05 21:19:07 -> 11 MB
2024-03-05 21:20:48 -> 12 MB
2024-03-05 21:22:08 -> 13 MB
2024-03-05 21:24:18 -> 14 MB
...
2024-03-05 21:01:10 -> 104 MB
2024-03-05 21:02:50 -> 105 MB
2024-03-05 21:04:30 -> 106 MB
2024-03-05 21:05:50 -> 107 MB
2024-03-05 21:07:10 -> 1 MB
2024-03-05 21:07:15 -> 2 MB
2024-03-05 21:07:26 -> 4 MB
The consumption starts at 1MB and roughly every one minute and forty-fifty seconds it consumes another 1MB till it reaches exactly 107MB. Then the consumption goes back to 1MB and the story repeats.
Our nginx logs are rotated whenever they hit the 200KB size. Not sure what is happening here.
Could anyone please guide us? Is it something with the program itself?
I am trying to advocate Nim's usage within my company and I would like to not have unforeseen edge cases that ultimately push back this beautiful language.
It always go to 107MB and back to 1MB? Never exceeds 107MB? When it goes back, always to 1MB and not 2MB? This happens automatically?
If so, I think there's no memory leak. If there is a memory leak, wouldn't it be something like 1MB -> 2MB -> ... 107MB -> 2MB -> 3MB -> ... -> 108MB -> 3MB -> 4MB -> ... -> 109MB -> ...?
database
OT for the question, as you use the SQLite library you don't need to open and close the 'connection' to it every time. You can open it once an leave it open until the program finishes, the close it. setControlCHook()
It always goes to 107MB and back to 1MB. No one restarts the program. There is no manual intervention at all.
Each loop takes a few milliseconds so this memory usage does not make sense.
I have added the memory report log to the repository under the name of memreport.log
Hi Araq,
I have added the nginx log, the executable and memory report log to the same repository.
I have not tried with -d:useMalloc since I did not know about it.
However, I have added the memory log report file, one of our nginx logs and the executable to the same repository.
also compiler instrumentation is your friend
https://lemire.me/blog/2016/04/20/no-more-leaks-with-sanitize-flags-in-gcc-and-clang/
https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
use it with --debugger:native
Thank you everyone for your input, leading to solve the issue.
Although, it still remains a mystery for me that why the memory utilization never exceeded 107MB and somehow we always "reset" back to 1MB.