Skip to content

Commit ae1f002

Browse files
authored
Reduce memory usage (RsyncProject#235)
In 2004, an allocation optimization has been added to the file list handling code, that preallocates 32k of file_struct pointers in a file_list. This optimization predates the incremental recursion feature, for which it is not appropriate anymore. When copying a tree containing a large number of small directories, using the incremental recursion, rsync allocates many short file_lists. Suddenly, the unused file_struct pointers can easily take 90-95% of the memory allocated by rsync.
1 parent 3911c23 commit ae1f002

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

flist.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ static void flist_expand(struct file_list *flist, int extra)
295295
flist->malloced = FLIST_START;
296296
else if (flist->malloced >= FLIST_LINEAR)
297297
flist->malloced += FLIST_LINEAR;
298+
else if (flist->malloced < FLIST_START_LARGE/16)
299+
flist->malloced *= 4;
298300
else
299301
flist->malloced *= 2;
300302

@@ -305,7 +307,7 @@ static void flist_expand(struct file_list *flist, int extra)
305307

306308
new_ptr = realloc_array(flist->files, struct file_struct *, flist->malloced);
307309

308-
if (DEBUG_GTE(FLIST, 1) && flist->malloced != FLIST_START) {
310+
if (DEBUG_GTE(FLIST, 1) && flist->files) {
309311
rprintf(FCLIENT, "[%s] expand file_list pointer array to %s bytes, did%s move\n",
310312
who_am_i(),
311313
big_num(sizeof flist->files[0] * flist->malloced),
@@ -2186,8 +2188,10 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
21862188
#endif
21872189

21882190
flist = cur_flist = flist_new(0, "send_file_list");
2191+
flist_expand(flist, FLIST_START_LARGE);
21892192
if (inc_recurse) {
21902193
dir_flist = flist_new(FLIST_TEMP, "send_file_list");
2194+
flist_expand(dir_flist, FLIST_START_LARGE);
21912195
flags |= FLAG_DIVERT_DIRS;
21922196
} else
21932197
dir_flist = cur_flist;
@@ -2541,10 +2545,13 @@ struct file_list *recv_file_list(int f, int dir_ndx)
25412545
#endif
25422546

25432547
flist = flist_new(0, "recv_file_list");
2548+
flist_expand(flist, FLIST_START_LARGE);
25442549

25452550
if (inc_recurse) {
2546-
if (flist->ndx_start == 1)
2551+
if (flist->ndx_start == 1) {
25472552
dir_flist = flist_new(FLIST_TEMP, "recv_file_list");
2553+
flist_expand(dir_flist, FLIST_START_LARGE);
2554+
}
25482555
dstart = dir_flist->used;
25492556
} else {
25502557
dir_flist = flist;

rsync.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -918,8 +918,9 @@ extern int xattrs_ndx;
918918
* Start the flist array at FLIST_START entries and grow it
919919
* by doubling until FLIST_LINEAR then grow by FLIST_LINEAR
920920
*/
921-
#define FLIST_START (32 * 1024)
922-
#define FLIST_LINEAR (FLIST_START * 512)
921+
#define FLIST_START (32)
922+
#define FLIST_START_LARGE (32 * 1024)
923+
#define FLIST_LINEAR (FLIST_START_LARGE * 512)
923924

924925
/*
925926
* Extent size for allocation pools: A minimum size of 128KB

0 commit comments

Comments
 (0)