새로운 동시 콜렉션을 읽었으며, 특히 ConcurrentBag가 내 관심을 끌었습니다. ConcurrentBag는 항목을 추적하기 위해 각 개별 스레드에서 로컬 세트를 내부적으로 보유하므로 스레드 자체가 범위를 벗어나면 여전히 ConcurrentBag에 의해 메모리에서 참조됩니다. 즉, 스레드가 요청한 메모리와 원시 리소스를 모두 의미합니까? (.NET 스레드 객체의 정확한 내부 동작을 알지 못해서 실례합니다.)ConcurrentBag에 메모리 리크가 있습니까?
많은 클라이언트가 작업을 추가하는 멀티 스레드 웹 서비스에 대해 1 개의 전역 ConcurrentBack이 있다고 가정 할 수 있습니다. 이러한 작업은 스레드 풀의 스레드에 의해 추가됩니다. 이제 스레드 풀은 스레드를 관리하는 매우 효율적인 방법이지만 작업량에 따라 스레드를 제거하고 만듭니다. 따라서, 그러한 웹 서비스는 근본적인 가방이 여전히 많은 파괴 된 스레드를 참조하고 있기 때문에 때때로 문제가 될 수 있습니다.
나는이 문제를 테스트하기 위해 빠른 응용 프로그램을 만들어 :static ConcurrentBag<int> bag = new ConcurrentBag<int>();
static void FillBag() { for (int i = 0; i < 100; i++) { bag.Add(i); } }
static void PrintState() { Console.WriteLine("Bag size is: {0}", bag.Count); }
static void Main(string[] args)
{
var remote = new Thread(x =>
{
FillBag();
PrintState();
});
// empty bag
PrintState();
// first 100 items are added on main thread
FillBag();
PrintState();
// second 100 items are added on remote thread
remote.Start();
remote.Join();
// since the remote thread is gone out of scope, what happened to its local storage which is part of the bag?
PrintState();
// now force a cleanup
WeakReference weakRemoteReference = new WeakReference(remote);
remote = null;
GC.Collect();
GC.WaitForPendingFinalizers();
// Now check if the thread still exists
if (weakRemoteReference.IsAlive)
Console.WriteLine("Remote thread still exists");
PrintState();
Console.ReadLine();
을 그리고 출력은 나의 이야기 확인 :
Bag size is: 0
Bag size is: 100
Bag size is: 200
Bag size is: 200
Remote thread still exists
Bag size is: 200
예상되는이 문제인가를 내 시험에서 실수를 않았다 또는 이것이 설계 결함으로 간주 될 수 있습니까?
원격 스레드가 범위를 벗어났다는 것을 명심해야합니다. "원격 스레드가 완료되었으므로" – Polity