2010-08-02 2 views
6

이상한 문제가 발생하여 다소 추적 할 수 있었지만 여전히 원인을 확인할 수 없습니다. 어쩌면 여기 누군가가 약간의 빛을 비출 수 있습니까?임베디드 플랫폼에서 스레드 클래스 메모리 할당이 이상 함

저는 PPCgnu604 툴 체인을 사용하여 C++로 개발 한 VxWorks 5.5 위에 PowerPC 프로세서를 실행하고 있습니다.

나는 수업과 같이 있습니다 : 내 응용 프로그램이 시작되면

class MyClass 
{ 
    public: 
    void run(void); 
    private: 
    CommandMesssageClass command; 
    StatusMessageClass status; 
}; 

, 동적으로 MyClass의 인스턴스를 할당하고 "실행"기능을 가리키는 스레드를 생성합니다. 본질적으로 그것은 단지 명령에 대한 폴링에 위치하며, 수신시 상태를 반환합니다.

이 클래스는 잘게 잘린 버전입니다. 간결성을 위해 다른 여러 가지 방법과 변수가 빠져 있습니다.

명령과 상태 메시지가 모두 개인 클래스 멤버로 정의되어있을 때 동적 메모리 할당이 없어야한다는 사실에도 불구하고 메모리에서 사용 가능한 바이트가 변경됩니다. 결정적이며 금리를 보장하는 절차가 필요하기 때문에 이것이 중요합니다.

메시지 선언 중 하나 또는 둘 다를 실행 함수로 이동하면 추가 할당없이 정상적으로 작동합니다.

저는 C++ 선언과 메모리 할당에 대한 기본적인 지식을 놓치고 있습니다. 내 이해는 내가 동적으로 instansiate 클래스 인스턴스를 만들 때 힙 (모든 멤버 변수 포함)에 완전히 할당됩니다. 여기서 볼 수있는 차이점은 메시지 선언을 실행 함수로 이동하면 대신 스택에 메시지 선언이 놓이게된다는 것입니다. 이 경우 힙은 클래스의 전체 크기에 부합 할만큼 충분히 큽니다. 특정 부분이 사용될 때까지 충분한 메모리를 할당하지 않는 것처럼 보이는 이유는 무엇입니까?

메시지 클래스는 자신의 동적 할당을 수행하지 않습니다. (그리고 그랬다면, 선언을 움직이면이 경우 동작이 바뀌지 않을 것이고 나는 힙의 크기가 여전히 변경된 것을 볼 수있을 것이다.)

메모리 할당을 모니터하기 위해 다음을 사용하고있다. VxWorks와 memLib (또는 memPartLib) 전화 :

memPartInfoGet(memSysPartId, &partitionStatus); 
... 
bytesFree = partitionStatus.numBytesFree; 

편집 :

가 MyClass의 개체 instansiated하고 초기화 루틴에서 초기화하고 코드 레이트 안전한 처리 들어간다 명확히한다. 이 시간 동안 직렬 회선 (명령 또는 상태 메시지 객체와의 첫 번째 상호 작용)을 통해 명령 메시지를 수신하면 추가 메모리가 할당됩니다 (또는 사용 가능한 바이트 수가 감소합니다). 동적 메모리 할당이 결정적이지 않기 때문에 이것은 나쁘다.

내가 설명한대로 클래스 변수를 이동하여 문제를 없앨 수있었습니다.

+0

문제가 무엇인지 명확하게 알지 못합니다. 클래스 멤버와 스택에 물건을 할당하는 데 더 많은 메모리를 사용하고 있습니까? 아니면 사용 된 메모리가 한 경우에 시간이 지남에 따라 달라지는 것입니까? – nos

+1

회원을 공개 섹션으로 올리면 sizeof (MyClass)가 변경됩니까? 그리고 얼마나 많은 메모리 할당이 변경됩니까? –

+1

* 할당이 변경 될 때 *? 더 작은 클래스 객체는 힙의 빈 블록에 쉽게 맞추어집니다. –

답변

2

나는 C++ 의 선언과 메모리 할당에 대한 이해를 위해 무언가를 놓치고 있어야합니다.

나는 그렇게 생각하지 않는다. 위에서 말한 모든 것은 정확합니다. 게임 프로그래머는이 동작에 항상 의존합니다.:-)

는 왜 특정 부분 가 사용되는 때까지 충분한 메모리를 할당 할 수없는 것입니까?

당신은 간결함을 위해 클래스의 배짱을 버렸습니다. 나는 비슷한 문제를 디버깅 한 경험이있다. 그리고 가장 좋은 추측은 거기에 라이브러리 함수 인 이라는 사실이다. 실제로 알지 못하는 런타임 할당을 만든다.

즉, 두 경우 모두 런타임 할당이 있지만 두 개의 다른 크기의 MyClass는 malloc 풀이 다르게 채워진다는 것을 의미합니다. run() 내부의 객체를 스택으로 옮겨서 MyClass를 동일한 크기로 패딩함으로써 이것을 증명할 수 있습니다. 무료 mem drop이 여전히 표시되면 해당 오브젝트가 힙 또는 스택에 있는지 여부와 아무런 관련이 없습니다. MyClass의 크기 때문에 발생하는 2 차 효과입니다.

malloc은 chunky입니다. 대부분의 구현은 malloc을 호출 할 때마다 일대일 할당을하지 않습니다. 대신에 풀에 메모리를 과도하게 할당하고 유지하며 필요한 경우 풀을 늘립니다.

저는 툴체인에 익숙하지 않지만 임베디드 시스템에서 예상치 못한 작은 할당에 대한 일반적인 용의자에는 ctype 함수 (로케일) 및 날짜/시간 함수 (시간대)가 포함됩니다.