tutorials:troubleshooting:memory
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
tutorials:troubleshooting:memory [2015/01/16 16:06] – [OS Memory Reports] miconda | tutorials:troubleshooting:memory [2021/06/01 18:44] (current) – [Insufficient Memory] giavac | ||
---|---|---|---|
Line 36: | Line 36: | ||
* too small PKG or SHM - insufficient size to accommodate all data needed to be stored in memory | * too small PKG or SHM - insufficient size to accommodate all data needed to be stored in memory | ||
- | * memory leak - some part of code allocates memory at runtine | + | * memory leak - some part of code allocates memory at runtime |
===== Monitoring Memory ===== | ===== Monitoring Memory ===== | ||
Line 46: | Line 46: | ||
< | < | ||
kamctl stats shmem | kamctl stats shmem | ||
+ | kamcmd mod.stats all shm | ||
</ | </ | ||
Line 52: | Line 53: | ||
< | < | ||
kamcmd pkg.stats | kamcmd pkg.stats | ||
+ | kamcmd mod.stats all pkg | ||
</ | </ | ||
Notice that for SHM only one group of statistics is printed, being one zone of memory, while for PKG you get a list with many groups of statistics, each specific for a Kamailio process (child). | Notice that for SHM only one group of statistics is printed, being one zone of memory, while for PKG you get a list with many groups of statistics, each specific for a Kamailio process (child). | ||
+ | |||
+ | In order to merge the free memory fragments one should enable memory join. Default is disabled (mem_join=0). | ||
+ | < | ||
+ | mem_join=1 | ||
+ | </ | ||
+ | |||
===== Analysis of Memory Incidents ===== | ===== Analysis of Memory Incidents ===== | ||
Line 63: | Line 71: | ||
* if the number of subscribers, | * if the number of subscribers, | ||
- | ===== Troubleshooting ===== | ||
===== Memory Manager Debugging ===== | ===== Memory Manager Debugging ===== | ||
Line 78: | Line 85: | ||
< | < | ||
- | MEMMNG=1 | + | MEMDBG=1 make cfg ... |
</ | </ | ||
Line 99: | Line 106: | ||
Then restart and wait a bit for getting some traffic processed. | Then restart and wait a bit for getting some traffic processed. | ||
+ | |||
+ | MEMMNG=0/ | ||
To get the list of chunks from memory manager, there are two ways: | To get the list of chunks from memory manager, there are two ways: | ||
Line 114: | Line 123: | ||
* for SHM memory: | * for SHM memory: | ||
< | < | ||
- | kamcmd cfg.set_now_int core mem_dump_shm | + | kamcmd cfg.set_now_int core mem_dump_shm |
</ | </ | ||
Line 136: | Line 145: | ||
For PKG is similar format, just SHM replaced with PKG in messages. | For PKG is similar format, just SHM replaced with PKG in messages. | ||
+ | To generate summary report, do: | ||
+ | |||
+ | < | ||
+ | # first set memlog lower than debug | ||
+ | kamcmd cfg.set_now_int core memlog 1 | ||
+ | |||
+ | kamcmd corex.shm_summary | ||
+ | </ | ||
+ | |||
+ | The log for f_malloc with debug enabled should look like: | ||
+ | |||
+ | < | ||
+ | 20(4082) NOTICE: fm_status: summarizing all alloc' | ||
+ | 20(4082) NOTICE: fm_status: | ||
+ | 20(4082) NOTICE: fm_status: | ||
+ | 20(4082) NOTICE: fm_status: | ||
+ | 20(4082) NOTICE: fm_status: | ||
+ | 20(4082) NOTICE: fm_status: | ||
+ | 20(4082) NOTICE: fm_status: | ||
+ | 20(4082) NOTICE: fm_status: | ||
+ | 20(4082) NOTICE: fm_status: | ||
+ | 20(4082) NOTICE: fm_status: | ||
+ | </ | ||
+ | |||
+ | If you dumped the status with qm_malloc, you can extract the logs from syslog and count the unique allocations with next commands: | ||
+ | |||
+ | < | ||
+ | grep qm_status / | ||
+ | |||
+ | # or: | ||
+ | # grep qm_status / | ||
+ | |||
+ | grep alloc qm_status.txt | awk '{ print substr( $0, 16, length($0) ) }' | sort | uniq -c | sort -k1n | ||
+ | </ | ||
===== Using GDB ===== | ===== Using GDB ===== | ||
Line 148: | Line 191: | ||
if($i> | if($i> | ||
if($a-> | if($a-> | ||
+ | printf " | ||
+ | p $a | ||
+ | p (void*)((char*)($a)+sizeof(struct qm_frag)) | ||
+ | printf " | ||
p *$a | p *$a | ||
end | end | ||
+ | end | ||
+ | set $a = ((struct qm_frag*)((char*)($a)+sizeof(struct qm_frag)+((struct qm_frag*)$a)-> | ||
+ | set $i = $i + 1 | ||
+ | end | ||
+ | </ | ||
+ | |||
+ | An alternative is to print all used chunks, but be aware that it may take some time: | ||
+ | |||
+ | |||
+ | <code c> | ||
+ | set $i=0 | ||
+ | set $a = mem_block-> | ||
+ | while($a < mem_block-> | ||
+ | if($a-> | ||
+ | printf " | ||
+ | p $a | ||
+ | p (void*)((char*)($a)+sizeof(struct qm_frag)) | ||
+ | printf " | ||
+ | p *$a | ||
end | end | ||
set $a = ((struct qm_frag*)((char*)($a)+sizeof(struct qm_frag)+((struct qm_frag*)$a)-> | set $a = ((struct qm_frag*)((char*)($a)+sizeof(struct qm_frag)+((struct qm_frag*)$a)-> | ||
Line 167: | Line 233: | ||
gdb --batch --command=/ | gdb --batch --command=/ | ||
</ | </ | ||
+ | |||
+ | ===== PKG With System Malloc ===== | ||
+ | |||
+ | Kamailio can be compiled to use system malloc and free for PKG needs. You have to remove the PKG_MALLOC define from Makefile.defs and can add DBG_SYS_MALLOC to get more verbosity with memory operations in debug mode. | ||
+ | |||
+ | Next is a diff showing the changes in Makefile.defs, | ||
+ | |||
+ | <code c> | ||
+ | diff --git a/ | ||
+ | index 3890668..12ca37a 100644 | ||
+ | --- a/ | ||
+ | +++ b/ | ||
+ | @@ -621,7 +621,7 @@ C_DEFS= $(extra_defs) \ | ||
+ | | ||
+ | | ||
+ | | ||
+ | - -DPKG_MALLOC \ | ||
+ | + -DDBG_SYS_MALLOC \ | ||
+ | | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | After updating Makefile.defs recompile and reinstall. | ||
+ | |||
+ | Other tools available out there (e.g., valgrind) can be then used to track the PKG memory operations done by Kamailio. | ||
===== OS Memory Reports ===== | ===== OS Memory Reports ===== | ||
Line 176: | Line 268: | ||
Here is the article that presents better the situation: | Here is the article that presents better the situation: | ||
- | | + | |
An relevant excerpt from the blog article: | An relevant excerpt from the blog article: |
tutorials/troubleshooting/memory.1421424408.txt.gz · Last modified: 2015/01/16 16:06 by miconda