2011-08-25 3 views
1

네트워킹 프로젝트에서 각 메시지 큐 (연결된 목록)가 여러 개체가 있습니다. 각 객체에는 몇 개의 클라이언트가 있으며 각 클라이언트에는 대기열에있는 노드에 대한 포인터가 있습니다. 클라이언트가 포인터를 가리키는 메시지를 받으면 포인터는 큐의 다음 메시지로 이동합니다. 이제 모든 클라이언트가 메시지를 받았을 때 메시지를 해제하여 메모리를 차지하지 않기를 바랍니다. 별도의 스레드가 객체를 통과하여 불필요한 메시지를 삭제하고 GC로 작동하지만이 작업을 수행하는 더 좋은 방법이 있습니까?다중 연결 큐

감사합니다.

+0

왜 별도의 스레드가 필요합니까? 코드가 이미 다중 스레드되지 않은 한, 코드 스레드를 안전하게 유지해야하는 복잡성이 있습니다. 보낸 후 정리 코드가 실행되지 않는 이유는 무엇입니까? – selbie

+0

성능에 영향을 미치기를 원하지 않았습니다. 그러나 참조 카운팅 아이디어가 좋습니다. – slartibartfast

+0

왜 성능에 영향을 미칠 것이라고 생각합니까? 프로파일 링 도구로 측정 했습니까? 성능 문제는 거의 자신이 생각하는 곳에서 발생하지 않습니다. – selbie

답변

3

이 문제를 해결하기 위해 참조 계산을 사용할 수 있습니다. 대기열 요소에 대한 모든 포인터가 바깥 쪽에서 (그리고 대기열 요소 사이에 절대로) 있다고 가정하면 대기 행렬 셀에 포인터 수를 저장합니다. 새 포인터를 추가 할 때마다이 참조 카운트가 증가하고 프로그램의 일부가 셀을 사용하여 완료 될 때마다 참조 카운트가 삭제되어 0에 도달하면 해제됩니다. 이렇게하면 셀에 대한 포인터가 남아있는 한 해제되지 않고 큐 셀에 대한 마지막 참조가 깨지면 즉시 회수됩니다. 이 작업을 수행하기 위해 별도의 스레드가 필요하지 않습니다.

+0

당신은 나를 때려 눕혔습니다. 나는 "각 클라이언트가 refcounted 메시지의 메시지 대기열을 유지"한다는 생각으로이를 수정합니다. – selbie

1

메시지에 구독자 목록이 있습니다.

구독자가 메시지를 열 때마다 구독자 수가 1 줄입니다. 따라서 구독자 수가 0 인 메시지를 찾는 데 문제가 있습니다.

나쁜 생각입니다.

개체 삭제 대기열을 마련해야합니다. 가입자가 메시지를 열 때마다 가입자 수를 확인합니다. 0이면 메시지 구독자가 메시지를 삭제 대기열에 제출합니다. 이제 GC 스레드는 삭제 대기열 만 모니터링해야합니다.

왜 카운터를 가지고 있어야합니다. 메시지 구독자 목록은 연결된 토큰 목록입니다. 각 가입자는 목록의 하나의 토큰과 연관됩니다. 토큰은 가입자에게 메시지가 있음을 알려줍니다.

메시지 큐가 네트워크에서 작동하는 경우 구독자 당 토큰이 생성되고 토큰은 순환 목록에 연결됩니다. 목록의 각 토큰에 대해 해당 토큰이 생성되어 구독자에게 전송됩니다. 구독자 요청 메시지 검색시 메시지 큐 관리자에 인증 토큰을 제출합니다. 메시지 대기열 관리는 토큰을 인증하고 구독자가 메시지에 액세스 할 수있게 한 다음 토큰을 목록에서 연결 해제합니다.

네트워크 메시지 대기열 또는 로컬 시스템 대기열에 관계없이 마지막 토큰이 연결 해제 된 경우 (원형 목록이므로 마지막 토큰임을 알 수 있음) 메시지는 삭제 대기열에 제출됩니다.