RAM / OOM 조각 모음 실패


11

이 질문은 상당히 길기 때문에 맨 위에 질문을 한 다음 질문을하는 방법을 살펴 보겠습니다.

  1. 연속 RAM이 부족하여 (Busybox 기반) rm이 실행되지 않았습니까?
  2. 그렇다면 시스템을 다시 시작하지 않고 DMA를 조각 모음하는 간단한 방법이 있습니까?
  3. 그렇지 않은 경우 원인은 무엇입니까? 앞으로 발생하지 않도록하려면 어떻게해야합니까?

지난 며칠 동안 테스트 시스템이 상당히 집중적으로 실행 된 후 시스템에 텔넷으로 연결하여 테스트 결과를 확인했습니다. 일부 데이터를 삭제하려고 할 때 시스템은 명령이 올바르게 실행 된 것처럼 명령 줄을 반환했습니다. 디렉토리에서 다른 결과 세트를 확인하려고 할 때 파일이 여전히 존재 함을 보았습니다 (ls 사용).

그 후, 점점 더 많은 쉘 명령이 예상대로 수행되지 않는 것을 알았습니다.

rm이 올바르게 실행되지 않은 후 dmesg 의 출력으로 시작하겠습니다 .

프로세스 6821 (rm)에서 길이 61440을 할당하지 못했습니다.

CPU 당 DMA :

CPU 0 : 안녕 : 0, 똥 : 1 USD : 0

Active_anon : 0 active_file : 1 inactive_anon : 0 inactive_file : 0 uncvictable : 6 dirty : 0 writeback : 0 unstable : 0 비어있는 : 821 slab : 353 매핑 : 0 pagetables : 0 바운스 : 0

DMA 사용 안함 : 3284kB 최소 : 360kB 낮음 : 448kB 높음 : 540kB active_anon : 0kB 비활성 _anon : 0kB active_file : 4kB 비활성 _ ​​파일 : 0kB unevictable : 24kB 존재 : 8128kB 페이지 _ 스캔 : 0 all_unreclaimable? 아니

lowmem_reserve [] : 0 0 0

DMA : 31 * 4kB 47 * 8kB 42 * 16kB 64 * 32kB 1 * 64kB 0 * 128kB 0 * 256kB 0 * 512kB 0 * 1024kB 0 * 2048kB 0 * 4096kB = 3284kB

14 개의 총 페이지 캐시 페이지

프로세스 데이터에 RAM을 할당 할 수 없음, errno 12

처음에는 연속 메모리의 가장 큰 부분에서 프로그램을 실행할 수 없다고 생각했습니다. DMA가 너무 조각화되어 시스템에서 메모리 조각 모음을 수행하는 방법을 찾아야한다는 것을 의미합니다.

그런 다음 빠른 수학 / 위생 검사를 수행하여 프로그램이 유일한 64kB 연속 메모리 슬롯에서 실행될 수 있어야한다는 것을 깨달았습니다. Rm이 61440 바이트 (60kB)를 요청했습니다.

오래된 "수동 조각 모음"을 수행하고 시스템을 재부팅했습니다. 시스템을 재부팅하면 / proc / buddyinfo가 출력됩니다.

Node 0, zone DMA 2 8 3 12 0 1 0 1 0 1 0

내가 의심되는지도 :

  • 2 x 4 kB
  • 8 x 8 kB
  • 3 x 16 kB
  • 12 x 32kB
  • 1 x 128 kB
  • 1 x 512 kB

그러나 위의 값 목록을 합하면 / proc / meminfo 출력과 일치하지 않습니다 .

MemTotal:           6580 kB
MemFree:            3164 kB
Buffers:               0 kB
Cached:              728 kB
SwapCached:            0 kB
Active:              176 kB
Inactive:            524 kB
Active(anon):          0 kB
Inactive(anon):        0 kB
Active(file):        176 kB
Inactive(file):      524 kB`
Unevictable:           0 kB
Mlocked:               0 kB
MmapCopy:            844 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:             0 kB
Mapped:                0 kB
Slab:               1268 kB
SReclaimable:        196 kB
SUnreclaim:         1072 kB
PageTables:            0 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:        3288 kB
Committed_AS:          0 kB
VmallocTotal:          0 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB

요컨대 내 질문은 다음과 같습니다.

  1. 연속 RAM이 부족하여 rm이 실행되지 않았습니까?
  2. 그렇다면 시스템을 다시 시작하지 않고 DMA를 조각 모음하는 간단한 방법이 있습니까?
  3. 그렇지 않은 경우 원인은 무엇입니까? 앞으로 발생하지 않도록하려면 어떻게해야합니까?

uClinux 버전 2.6.30을 실행하는 Lantronix의 XPort Pro (8MB, Linux OS)를 사용하고 있습니다. 사용중인 쉘이 허쉬합니다.


사소한 점 : 메모리 청크 목록에서 1 x 2048 kB를 제외했습니다. 포함하면 합계는 3192 kB이며 / proc / meminfo에 나열된 3164 kB에 매우 가깝습니다.
Alex Selby

답변:


11

귀하의 질문 2 (메모리 조각 모음)에서 https://www.kernel.org/doc/Documentation/sysctl/vm.txt 에서 인용 하십시오 .

compact_memory

CONFIG_COMPACTION이 설정된 경우에만 사용할 수 있습니다. 1이 파일에 기록되면 사용 가능한 메모리가 가능한 경우 인접한 블록에서 사용 가능한 메모리가 확보되도록 모든 영역이 압축됩니다. 예를 들어 프로세스가 필요에 따라 메모리를 직접 압축하기는하지만, 이는 예를 들어 거대한 페이지를 할당 할 때 중요 할 수 있습니다.

이는 다음 명령 (루트 권한으로 실행되고 위에서 언급 한 커널 옵션이 활성화 된 경우)을 의미합니다.

echo 1 > /proc/sys/vm/compact_memory

커널에게 가능한 많은 메모리 조각 모음을 시도하도록 지시해야합니다. 예를 들어 일부 RHEL6 버전에서는 커널이 충돌 할 수 있습니다.


1
돌아와서 오래된 질문에 대해 의견을 보내 주셔서 감사합니다!
OldTinfoil

7

시간이 조금 걸렸지 만 세 가지 하위 질문 모두에 대한 답변을받을 때까지 응답을 보류 할 것이라고 생각했습니다.

시작하기 전에 작업 메모리를 "조각 모음"할 때의 올바른 용어를 "컴팩 팅"작업 메모리라고합니다.

1. 연속 RAM이 부족하여 rm이 실행되지 않았습니까?

내 결론에 맞았습니다. 연속 RAM이 충분하지 않아 rm이 실행되지 않았습니다. 시스템이 RAM을 확보하고 조각화하여이를 회수 할 수 없었습니다.

2. 그렇다면 시스템을 다시 시작하지 않고 DMA 조각 모음을 수행하는 간단한 방법이 있습니까?

임베디드 시스템을 다시 시작하지 않고 메모리를 압축하는 방법이 없다는 것이 밝혀졌습니다. MMU가없는 시스템의 경우 예방은 게임의 이름입니다.

저의 일부는 소프트웨어에서 MMU를 에뮬레이트하기 위해 리눅스 커널을 해킹 할 수 있는지 숙고합니다. 가능하다면 누군가 이미 해냈을 것이라고 생각합니다. 나는 완전히 새로운 개념을 상상할 수 없다;)

3. 앞으로 발생하지 않도록하려면 어떻게해야합니까?

이 프로젝트에서는 cron을 사용하여 필요할 때마다 수동으로 프로그램을 시작했습니다. 이렇게하는 가장 좋은 방법은 시작할 때 프로그램을 호출 한 다음 필요할 때까지 프로그램을 강제로 잠그는 것입니다. 이런 식으로, 매번 사용할 때마다 메모리를 할당 할 필요가 없습니다. 따라서 조각화를 줄입니다.

프로젝트의 첫 번째 반복에서 우리는 중요한 기능 (예 : rm)을 수행하기 위해 쉘 스크립트 호출에 의존했습니다. 필요하지 않은 휠을 다시 발명 할 필요성을 보지 못했습니다.

그러나 MMU가없는 시스템의 경우 가능한 경우 쉘을 피하는 것이 좋습니다.

( 질문 , 실행하면 어떻게됩니까 ls -la /path/to/directory/ | grep file-i-seek?)

( 답변 : 새로운 하위 프로세스를 시작합니다)

C 프로그램에서 일부 핵심 쉘 스크립트 기능을 구현해야하는 경우 BusyBox에 사용 된 소스 코드를 확인하는 것이 좋습니다 . 임베디드 시스템에서 C를 사용하게 될 것입니다.


돌아와서 결과를 공유해 주셔서 감사합니다.
Caleb

3
MMU 에뮬레이션이 어렵습니다 ... MMU가 없으면 모든 프로그램이 실제 주소를 메모리 버스에 나타나는대로 직접 사용합니다. 하나를 에뮬레이트 할 수는 있지만 실제 MMU와 마찬가지로 모든 메모리 액세스를 가로 챌 필요가 있습니다. 성능이 끔찍할 것입니다. 또는 간접 포인터 (Mac OS Classic처럼 "핸들"이라고 함)를 사용할 수 있지만 완전히 어려운 API와 선점에 직면 한 매우 어려운 API가 있습니다 (Mac OS Classic은 협력적인 멀티 태스킹을 사용함) .
derobert

돌아와서 답변을 작성하는 데 시간을 보내 주셔서 감사합니다. MacOS classic이 그랬다는 것을 몰랐습니다.
OldTinfoil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.