Java iş parçacığı oluşturma pahalıdır, çünkü işin oldukça az bir kısmı vardır:
- İplik yığını için büyük bir bellek bloğu tahsis edilmeli ve başlatılmalıdır.
- Yerel iş parçacığını ana bilgisayar işletim sistemine oluşturmak / kaydetmek için sistem çağrıları yapılmalıdır.
- Tanımlayıcıların oluşturulması, başlatılması ve JVM iç veri yapılarına eklenmesi gerekir.
İpliğin canlı olduğu sürece kaynakları bağlaması açısından da pahalıdır; örneğin iplik yığını, yığından erişilebilen nesneler, JVM iplik tanımlayıcıları, işletim sistemi yerel iplik tanımlayıcıları.
Tüm bunların maliyeti platforma özgüdür, ancak şimdiye kadar karşılaştığım herhangi bir Java platformunda ucuz değildir.
Bir Google araması, 2002 vintage Linux çalıştıran 2002 vintage çift işlemcili Xeon'da Sun Java 1.4.1'de saniyede ~ 4000 iş parçacığı oluşturma oranı rapor eden eski bir ölçüt buldu . Daha modern bir platform daha iyi rakamlar verecektir ... ve metodoloji hakkında yorum yapamam ... ama en azından iplik yaratmanın ne kadar pahalı olabileceğine dair bir basketbol sahası veriyor .
Peter Lawrey'in kıyaslaması, iş parçacığı oluşturmanın bu günlerde mutlak olarak önemli ölçüde daha hızlı olduğunu gösteriyor, ancak bunun ne kadarının Java ve / veya OS ... veya daha yüksek işlemci hızlarındaki iyileştirmelerden kaynaklandığı belli değil. Ancak, her seferinde yeni bir iş parçacığı oluşturma / başlatmaya karşı bir iş parçacığı havuzu kullanırsanız , sayıları hala 150'den fazla bir iyileşme olduğunu gösterir. (Ve bunların hepsinin göreceli olduğuna dikkat çekiyor ...)
(Yukarıda "yeşil iplikler" yerine "yerel iplikler" olduğu varsayılır, ancak modern JVM'lerin tümü performans nedenleriyle yerel iplikleri kullanır. Yeşil iplikler oluşturmak için daha ucuzdur, ancak diğer alanlarda ödeme yaparsınız.)
Bir Java iş parçacığı yığını gerçekten tahsis nasıl görmek için biraz kazma yaptım. Linux'ta OpenJDK 6 durumunda, iş parçacığı yığını pthread_create
yerel iş parçacığını oluşturan çağrı tarafından ayrılır . (JVM önceden yerleştirilmiş pthread_create
bir yığını geçmez .)
Daha sonra, pthread_create
yığın içinde mmap
aşağıdaki gibi bir çağrı ile ayrılır :
mmap(0, attr.__stacksize,
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
Buna göre man mmap
, MAP_ANONYMOUS
bayrak belleğin sıfırlanmasına neden olur.
Bu nedenle, yeni Java iş parçacığı yığınlarının (JVM spesifikasyonuna göre) sıfırlanması gerekli olmasa da, pratikte (en azından Linux'ta OpenJDK 6 ile) sıfırlanırlar.