内存分配太慢
Memory allocation is too slow
我是 运行 AWS 上的一些内存密集型服务(m4.15xlarge
和 m5.12xlarge
实例)并且注意到在特定条件下(通常在特定内存限制之后)时间分配额外内存的时间急剧增加(高达 50 倍)。
发生时 htop
在内核模式下显示 100%(红色)并且 perf top
看起来像这样:
62.82% [kernel] [k] pageblock_pfn_to_page
15.21% [kernel] [k] clear_page_c_e
5.78% [kernel] [k] get_pfnblock_flags_mask
3.06% [kernel] [k] compaction_alloc
1.59% [kernel] [k] clear_huge_page
1.49% [kernel] [k] _raw_spin_lock
1.41% [kernel] [k] async_page_fault
1.29% a.out [.] memTest
0.99% [kernel] [k] get_page_from_freelist
0.85% [kernel] [k] compact_zone
0.69% [kernel] [k] try_charge
0.51% [kernel] [k] error_entry
...
在正常操作期间,它看起来像这样:
66.29% [kernel] [k] clear_page_c_e
7.05% [kernel] [k] clear_huge_page
3.91% a.out [.] memTest
3.66% [kernel] [k] _raw_spin_lock
3.12% [kernel] [k] async_page_fault
2.68% [kernel] [k] get_page_from_freelist
1.93% [kernel] [k] _cond_resched
1.49% [kernel] [k] try_charge
1.12% [kernel] [k] error_entry
1.01% [kernel] [k] retint_user
0.93% [kernel] [k] handle_mm_fault
0.77% [kernel] [k] mem_cgroup_try_charge
0.67% [kernel] [k] pmd_pfn
0.66% [kernel] [k] __rmqueue.isra.80
...
我不完全明白是什么触发了这种行为。有时很难重现,但有时它一直在发生。
我假设这与 AWS 虚拟化有关(所以问题是间歇性的,我将其归因于 "neighbors") (请参阅下面的 更新)。我也无法在 m5.metal
机器上重现该问题。
我能够使用一个在循环中分配和初始化内存的简单 C 程序重现该问题:
void memTest(long chunk, long total) {
struct timeval prev, cur = {0,0}, lastProgress = {0,0};
int i, j;
int num = total / chunk;
int p, progress = -1;
uint8_t *data[num];
get_now(&prev);
for (i = 0; i < num; i++) {
data[i] = malloc(chunk);
for (j = 0; j < chunk; j += 4096) {
data[i][j] = rand()%265;
}
get_now(&cur);
add(delta(&prev, &cur));
prev = cur;
p = (i * 20) / num * 5;
if (p != progress) {
if (lastProgress.tv_sec == 0) {
printf("%s: %02d%%\n", format(&cur), p);
} else {
double elapsed = delta(&lastProgress, &cur);
printf("%s: %02d%% (%gms)\n", format(&cur), p, elapsed);
}
lastProgress = cur;
progress = p;
}
}
}
m5.12xlarge$ ./a.out --total 182714368000 --chunk 16777216
2019-03-27 05:03:22.805827: 00%
2019-03-27 05:03:25.035575: 05% (2229.75ms)
2019-03-27 05:03:27.244955: 10% (2209.38ms)
2019-03-27 05:03:29.458160: 15% (2213.2ms)
2019-03-27 05:03:31.665313: 20% (2207.15ms)
2019-03-27 05:03:33.871949: 25% (2206.64ms)
2019-03-27 05:03:36.075955: 30% (2204.01ms)
2019-03-27 05:03:38.284512: 35% (2208.56ms)
2019-03-27 05:03:40.489039: 40% (2204.53ms)
2019-03-27 05:03:42.697444: 45% (2208.41ms)
2019-03-27 05:03:44.902268: 50% (2204.82ms)
2019-03-27 05:03:47.110703: 55% (2208.43ms)
2019-03-27 05:03:49.315001: 60% (2204.3ms)
2019-03-27 05:03:51.523370: 65% (2208.37ms)
2019-03-27 05:03:53.728535: 70% (2205.16ms)
2019-03-27 05:03:55.936081: 75% (2207.55ms)
2019-03-27 05:03:58.141149: 80% (2205.07ms)
2019-03-27 05:04:00.349740: 85% (2208.59ms)
2019-03-27 05:04:02.553894: 90% (2204.15ms)
2019-03-27 05:04:04.762675: 95% (2208.78ms)
2019-03-27 05:04:41.470692: 100% (36708ms) . <---
这次我只能解决接近内存限制的问题,但即使在 20Gb(可用的 186Gb)上我也能解决。
如果有人能说明正在发生的事情以及如何消除这种影响,我将不胜感激。
更新:
我更深入地研究了这个问题,目前责怪恰好在 m5.12xlarge
上启用 (always
) 和禁用 (madvise
) 的透明大页面支持 (THP)在 m5.metal
上。切换机器上的设置后,我在 m5.metal
上遇到了问题,在 m5.12xlarge
.
上问题消失了
我是 运行 AWS 上的一些内存密集型服务(m4.15xlarge
和 m5.12xlarge
实例)并且注意到在特定条件下(通常在特定内存限制之后)时间分配额外内存的时间急剧增加(高达 50 倍)。
发生时 htop
在内核模式下显示 100%(红色)并且 perf top
看起来像这样:
62.82% [kernel] [k] pageblock_pfn_to_page
15.21% [kernel] [k] clear_page_c_e
5.78% [kernel] [k] get_pfnblock_flags_mask
3.06% [kernel] [k] compaction_alloc
1.59% [kernel] [k] clear_huge_page
1.49% [kernel] [k] _raw_spin_lock
1.41% [kernel] [k] async_page_fault
1.29% a.out [.] memTest
0.99% [kernel] [k] get_page_from_freelist
0.85% [kernel] [k] compact_zone
0.69% [kernel] [k] try_charge
0.51% [kernel] [k] error_entry
...
在正常操作期间,它看起来像这样:
66.29% [kernel] [k] clear_page_c_e
7.05% [kernel] [k] clear_huge_page
3.91% a.out [.] memTest
3.66% [kernel] [k] _raw_spin_lock
3.12% [kernel] [k] async_page_fault
2.68% [kernel] [k] get_page_from_freelist
1.93% [kernel] [k] _cond_resched
1.49% [kernel] [k] try_charge
1.12% [kernel] [k] error_entry
1.01% [kernel] [k] retint_user
0.93% [kernel] [k] handle_mm_fault
0.77% [kernel] [k] mem_cgroup_try_charge
0.67% [kernel] [k] pmd_pfn
0.66% [kernel] [k] __rmqueue.isra.80
...
我不完全明白是什么触发了这种行为。有时很难重现,但有时它一直在发生。
我假设这与 AWS 虚拟化有关(所以问题是间歇性的,我将其归因于 "neighbors") (请参阅下面的 更新)。我也无法在 m5.metal
机器上重现该问题。
我能够使用一个在循环中分配和初始化内存的简单 C 程序重现该问题:
void memTest(long chunk, long total) {
struct timeval prev, cur = {0,0}, lastProgress = {0,0};
int i, j;
int num = total / chunk;
int p, progress = -1;
uint8_t *data[num];
get_now(&prev);
for (i = 0; i < num; i++) {
data[i] = malloc(chunk);
for (j = 0; j < chunk; j += 4096) {
data[i][j] = rand()%265;
}
get_now(&cur);
add(delta(&prev, &cur));
prev = cur;
p = (i * 20) / num * 5;
if (p != progress) {
if (lastProgress.tv_sec == 0) {
printf("%s: %02d%%\n", format(&cur), p);
} else {
double elapsed = delta(&lastProgress, &cur);
printf("%s: %02d%% (%gms)\n", format(&cur), p, elapsed);
}
lastProgress = cur;
progress = p;
}
}
}
m5.12xlarge$ ./a.out --total 182714368000 --chunk 16777216
2019-03-27 05:03:22.805827: 00%
2019-03-27 05:03:25.035575: 05% (2229.75ms)
2019-03-27 05:03:27.244955: 10% (2209.38ms)
2019-03-27 05:03:29.458160: 15% (2213.2ms)
2019-03-27 05:03:31.665313: 20% (2207.15ms)
2019-03-27 05:03:33.871949: 25% (2206.64ms)
2019-03-27 05:03:36.075955: 30% (2204.01ms)
2019-03-27 05:03:38.284512: 35% (2208.56ms)
2019-03-27 05:03:40.489039: 40% (2204.53ms)
2019-03-27 05:03:42.697444: 45% (2208.41ms)
2019-03-27 05:03:44.902268: 50% (2204.82ms)
2019-03-27 05:03:47.110703: 55% (2208.43ms)
2019-03-27 05:03:49.315001: 60% (2204.3ms)
2019-03-27 05:03:51.523370: 65% (2208.37ms)
2019-03-27 05:03:53.728535: 70% (2205.16ms)
2019-03-27 05:03:55.936081: 75% (2207.55ms)
2019-03-27 05:03:58.141149: 80% (2205.07ms)
2019-03-27 05:04:00.349740: 85% (2208.59ms)
2019-03-27 05:04:02.553894: 90% (2204.15ms)
2019-03-27 05:04:04.762675: 95% (2208.78ms)
2019-03-27 05:04:41.470692: 100% (36708ms) . <---
这次我只能解决接近内存限制的问题,但即使在 20Gb(可用的 186Gb)上我也能解决。
如果有人能说明正在发生的事情以及如何消除这种影响,我将不胜感激。
更新:
我更深入地研究了这个问题,目前责怪恰好在 m5.12xlarge
上启用 (always
) 和禁用 (madvise
) 的透明大页面支持 (THP)在 m5.metal
上。切换机器上的设置后,我在 m5.metal
上遇到了问题,在 m5.12xlarge
.