오늘은 일련의 프로그램에 대한 스트레스 테스트를 하고 있습니다. 프로그램의 입력 부하를 크게 늘렸고 처음에는 작동했지만 메모리를 빨아들이는 눈에 띄는 메모리 누수가 발생했습니다. 유일한 문제는 1) Valgrind
누출이 없고 2) 패킷 수집 속도가 높은 경우에만 발생한다는 것입니다.
아마도 미친 아이디어 중 하나는 내 시스템이 패킷이 들어오는 속도로 패킷을 출력할 대역폭이 부족하기 때문에 추가 메모리가 메시지 대기열로 이동하여 점점 더 큰 데이터 버퍼를 전송하게 될 수 있다는 것입니다. 메모리를 많이 차지하는 프로그램이 TCP 소켓에서 데이터를 읽고 명명된 파이프에 쓰고 있음을 보여줍니다. 그래서 세 가지 질문이 있습니다.
TCP/IP 또는 명명된 파이프의 경우 디스패치할 데이터를 저장하는 데 사용되는 메모리 큐가 무한정 커질 수 있습니까?
큐가 커질 수 있고 커진다면 여전히 내 프로그램(TCP에서 읽고 명명된 파이프로 출력하는 프로그램)이 메모리를 많이 차지하는 것으로 표시됩니까, 아니면 메모리가 시스템 메모리로 표시됩니까?
이러한 대기열에 할당된 메모리를 확인하는 데 사용할 수 있는 명령이 있습니까? 센토스를 쓰고 있어요
물론, 그것이 제가 유출한 이유는 아니라고 생각합니다만, 또 다른 것이 무엇인지 추측할 수 없어서 물어볼 수밖에 없었습니다!
답변1
- 일반적으로 말하면 매우 제한적입니다. 있지만둘(적어도) 이러한 버퍼가 존재할 수 있는 곳은 다음과 같습니다.
- 커널에서. 확실히 경계가 있습니다. 나는 FIFO가 하드코딩되어 있고 /를
/proc/sys/kernel/tcp_wmem
사용하여 TCP를 (및 rmem) 및 (proc 제한 내에서) 설정할 수 있다고 생각합니다 . 자세한 내용은 tcp(7) 맨페이지를 참조하십시오.setsockopt
SO_SNDBUF
SO_RCVBUF
- 귀하의 신청서에. write 등을 직접 호출하지 않으면 사용 중인 라이브러리에 자체 버퍼가 있을 수 있습니다. 이것들가능한무제한입니다.
- 좋아요 실제로 세 번째 장소는 네트워크 카드의 RAM입니다. 납땜 없이는 특정(상당히 작은) 한도 이상으로 늘릴 수 있는 방법이 없으므로 무시했습니다. 아, 네트워크 카드의 DMA용 전송 링 버퍼도 있습니다. 다시 말하지만, 고정된 크기(ethtool은 가능한 경우 조정됨)입니다.
- 커널에서. 확실히 경계가 있습니다. 나는 FIFO가 하드코딩되어 있고 /를
- 커널은 시스템 메모리로 표시됩니다. 애플리케이션에 있는 항목은 애플리케이션의 가상 크기(및 상주 크기 등)의 일부로 나타납니다.
netstat -t
각 TCP 연결에 대한 보내기 및 받기 대기열의 현재 크기가 표시됩니다. 귀하의 라이브러리에 보관된 콘텐츠에 대해서는 해당 문서를 확인하세요.
기억하세요, 기억은 그렇지 않습니다.방법을 제공드디어 풀어보면. 애플리케이션의 대기열 증가로 인해 어려움을 겪고 있다면 이는 경품이 아닙니다. 메모리 조각화 증가로 고통받고 있는 경우에도 마찬가지입니다.