annotate OrthancServer/Resources/ImplementationNotes/memory_consumption.txt @ 5294:e0e2aee4453e

Modality worklists plugin: allow searching on private tags (exact match only)
author Alain Mazy <am@osimis.io>
date Wed, 10 May 2023 12:52:35 +0200
parents f5907aecbaed
children 566e8d32bd3a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5153
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
1 In Orthanc 1.11.3, we have introduced a Housekeeper thread that
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
2 tries to give back unused memory back to the system. This is implemented
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
3 by calling malloc_trim every 100ms.
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
4
5156
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
5
5153
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
6 Here is how we validated the effect of this new feature:
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
7 -------------------------------------------------------
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
8
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
9 We compared the behaviour of 2 osimis/orthanc Docker images from the mainline
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
10 on Feb 1st 2023. One image without the call to malloc_trim and the other with
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
11 this call.
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
12
5156
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
13
5153
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
14 1st test: unconstrained Docker containers
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
15 .........................................
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
16
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
17 5 large studies are uploaded to each instance of Orthanc (around 1GB in total).
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
18 A script triggers anonymization of these studies as quick as possible.
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
19 We compare the memory used by the containers after 2 minutes of execution
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
20 (using `docker stats`):
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
21 - without malloc_trim: 1500 MB
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
22 - with malloc_trim: 410 MB
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
23
5156
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
24
5153
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
25 2nd test: memory constrained Docker containers
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
26 ..............................................
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
27
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
28 Each Orthanc container is limited to 400MB (through the docker-compose configuration
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
29 `mem_limit: 400m`)
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
30 5 large studies are uploaded to each instance of Orthanc (around 1GB in total).
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
31 Each study is anonymized manually, one by one and then, we repeat the operation.
5157
Alain Mazy <am@osimis.io>
parents: 5156
diff changeset
32 We compare the memory used by the containers after each anonymization
5153
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
33 (using `docker stats`):
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
34
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
35 # study without malloc_trim with_malloc_trim
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
36 0 ~ 50 MB ~ 50 MB
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
37 1 ~ 140 MB ~ 140 MB
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
38 2 ~ 390 MB ~ 340 MB
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
39 3 ~ 398 MB ~ 345 MB
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
40 4 out-of-memory crash ~ 345 MB
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
41 5..20 ~ 380 MB (stable)
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
42
5156
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
43
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
44 3rd test: memory constrained Docker containers
5155
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
45 ..............................................
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
46
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
47 In this last test, we lowered the memory allocation to 300MB and have been able to
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
48 run the first test script for at least 7 minutes (we did not try longer !). The
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
49 consumed memory is most of the time around 99% but it seems that the memory constrain
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
50 is handled correctly. Note that, in this configuration, 128 MB are used by the Dicom
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
51 Cache.
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
52
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
53 The same test without malloc_trim could never run for more than 35 seconds.
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
54
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
55
5156
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
56 4th test: performance impact of malloc_trim and available memory
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
57 ................................................................
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
58
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
59 In this test, we have measured the time required to anonymize a 2000 instances study
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
60 with various configurations. It appears that malloc_trim or the total amount
5158
02cfd23a556a CppCheck
Alain Mazy <am@osimis.io>
parents: 5157
diff changeset
61 of memory available in the system has no significant impact on performance.
5156
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
62
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
63 - No malloc trim, 300 MB in the system: ~ 38s
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
64 - No malloc trim, 1500 MB in the system: ~ 38s
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
65 - With malloc trim, 300 MB in the system: ~ 38s
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
66 - With malloc trim, 1500 MB in the system: ~ 38s
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
67
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
68
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
69 Conclusion:
Alain Mazy <am@osimis.io>
parents: 5155
diff changeset
70 ----------
5155
Alain Mazy <am@osimis.io>
parents: 5153
diff changeset
71
5157
Alain Mazy <am@osimis.io>
parents: 5156
diff changeset
72 The use of malloc_trim reduces the overall memory consumption of Orthanc
Alain Mazy <am@osimis.io>
parents: 5156
diff changeset
73 and avoids some of the out-of-memory situations.
Alain Mazy <am@osimis.io>
parents: 5156
diff changeset
74
Alain Mazy <am@osimis.io>
parents: 5156
diff changeset
75 However, it does not guarantee that Orthanc will never reach a
5153
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
76 out-of-memory error, especially on very constrained systems.
5157
Alain Mazy <am@osimis.io>
parents: 5156
diff changeset
77
5153
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
78 Depending on the allocation pattern, the Orthanc memory can get
5157
Alain Mazy <am@osimis.io>
parents: 5156
diff changeset
79 very fragmented and increase regularly since malloc_trim only releases memory
5153
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
80 at the end of each of malloc arena. However, note that, even long before the
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
81 introduction of malloc_trim, we have observed Orthanc instances running for years
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
82 without ever reaching out-of-memory errors and Orthanc is usually considered as
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
83 very stable.
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
84
5157
Alain Mazy <am@osimis.io>
parents: 5156
diff changeset
85 Moreover, before each release, Orthanc integration tests are run against Valgrind
Alain Mazy <am@osimis.io>
parents: 5156
diff changeset
86 and no memory leaks have been identified.
5153
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
87
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
88
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
89 malloc_trim documentation
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
90 -------------------------
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
91
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
92 from (https://stackoverflow.com/questions/40513716/malloc-trim0-releases-fastbins-of-thread-arenas)
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
93
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
94 If possible, gives memory back to the system (via negative
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
95 arguments to sbrk) if there is unused memory at the `high' end of
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
96 the malloc pool. You can call this after freeing large blocks of
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
97 memory to potentially reduce the system-level memory requirements
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
98 of a program. However, it cannot guarantee to reduce memory. Under
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
99 some allocation patterns, some large free blocks of memory will be
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
100 locked between two used chunks, so they cannot be given back to
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
101 the system.
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
102
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
103 The `pad' argument to malloc_trim represents the amount of free
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
104 trailing space to leave untrimmed. If this argument is zero,
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
105 only the minimum amount of memory to maintain internal data
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
106 structures will be left (one page or less). Non-zero arguments
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
107 can be supplied to maintain enough trailing space to service
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
108 future expected allocations without having to re-obtain memory
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
109 from the system.
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
110
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
111 Malloc_trim returns 1 if it actually released any memory, else 0.
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
112 On systems that do not support "negative sbrks", it will always
217863b09457 malloc_trim doc
Alain Mazy <am@osimis.io>
parents:
diff changeset
113 return 0.
5159
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
114
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
115
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
116 glibc internals
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
117 ---------------
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
118
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
119 Lots of useful info here: https://man7.org/linux/man-pages/man3/mallopt.3.html
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
120
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
121 summary:
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
122 - malloc uses sbrk() or mmap() to allocate memory. mmap() is used to allocate
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
123 large memory chunks, larger than M_MMAP_THRESHOLD.
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
124 - about mmap(): On the other hand, there are some disadvantages to
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
125 the use of mmap(2): deallocated space is not placed on the
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
126 free list for reuse by later allocations; memory may be
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
127 wasted because mmap(2) allocations must be page-aligned;
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
128 and the kernel must perform the expensive task of zeroing
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
129 out memory allocated via mmap(2). Balancing these factors
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
130 leads to a default setting of 128*1024 for the
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
131 M_MMAP_THRESHOLD parameter.
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
132 - free() employs sbrk() to release memory back to the system and M_TRIM_THRESHOLD
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
133 specifies the minimum size that is released. So, even without
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
134 malloc_trim, Orthanc is able to give back memory to the system.
f5907aecbaed conditional usage of malloc_trim
Alain Mazy <am@osimis.io>
parents: 5158
diff changeset
135 - free() never gives back block allocated by mmap() to the system, only malloc_trim() does !