OOM Killer 값은 항상 설정값보다 1 작습니다.

OOM Killer 값은 항상 설정값보다 1 작습니다.

oom_adj메모리 부족 킬러의 값을 설정하려고 하는데 , 이를 수행할 때마다(프로세스에 관계없이) 내가 설정한 값보다 1 작은 값이 반환됩니다(적어도 양의 정수의 경우). 시작한 이후로 음수로 시도하지 않았습니다. 이러한 프로세스가 OOM Killer에 의해 먼저 종료되기를 바랍니다.

[root@server ~]# echo 10 > /proc/12581/oom_adj
[root@server ~]# cat /proc/12581/oom_adj
9
[root@server ~]# echo 9 > /proc/12581/oom_adj
[root@server ~]# cat /proc/12581/oom_adj
8
[root@server ~]# echo 8 > /proc/12581/oom_adj
[root@server ~]# cat /proc/12581/oom_adj
7
[root@server ~]# echo 7 > /proc/12581/oom_adj
[root@server ~]# cat /proc/12581/oom_adj
6
[root@server ~]# 

이것이 예상되는 동작입니까? 그렇지 않다면 왜 이런 일이 발생합니까?

답변1

oom_adj더 이상 사용되지 않으며 레거시 목적으로만 사용됩니다. Linux는 내부적으로 oom_score_adj더 큰 범위( oom_adj최대 15, oom_score_adj최대 1000)를 사용합니다.

작성할 때마다 oom_adj(9라고 가정) 커널은 다음을 수행합니다.

oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE;

oom_score_adj에 저장하면 OOM_SCORE_ADJ_MAX1000이고 OOM_DISABLE-17입니다.

oom_adj=(9 * 1000) / 17 ~= 529.411따라서 9의 경우 이 값은 정수이므로 529를 얻게 됩니다 .oom_score_adj

oom_adj이제 커널을 읽으면 다음과 같은 작업이 수행됩니다.

oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) / OOM_SCORE_ADJ_MAX;

따라서 529의 경우 다음과 같은 결과를 얻게 됩니다. oom_adj = (529 * 17) / 1000 = 8.993커널이 정수와 정수 산술을 사용하므로 이는 8이 됩니다.

따라서 9를 쓰고 고정 소수점/정수 연산으로 인해 8을 얻습니다.

관련 정보