11 Mart 2016 Cuma

IIS Express 32bit modu ve StackSize (maxStackSize) yetersizliği çözümü

Asp.Net üzerinde geliştirilen bir uygulamada StackOverflow hatası alındığında muhtemelen bir array için yüksek bir değer baştan tanımlanmıştır. Yada herhangi bir şekilde (muhtemelen gerekmediği halde) büyük miktarda bellek kullanımına sebep olabilecek bir tanım yapılması.
Alternatif bir örnek büyük bir text dosyayı stream olarak okumak yerine tek seferde belleğe alınmaya çalışılması...

Hatayı dışardan bir sınıf kullandığınızda alıyorsanız ve başkaları bu hatayı almıyorsa oluşacak hatalardan biri StackSize ile ilgili olabilir. Yani dışardan çağırdığınız sınıfın bellek kullanımı ile ilgili.

Son tecrübemde Java üzerinde geliştirilmiş bir sınıfın IKvm ile .Net'e port edilmiş halini Console uygulamasında hatasız çalışırken Visual Studio'da Asp.net projesi olarak çalıştırmayı denediğimde hata oluşuyordu. (StackTrace kaybolduğundan hata StackOverflow olarak orataya çıkmıyordu.)

Hatayı araştırdığımda iki alternatif öneri vardı:

1. İlgili sınıfı yeni bir thread açıp MaxStackSize belirtip orda çalıştırmak.
2. Visual Studio ile gelen IIS Express'i kullanmak yerine Servis olarak kurulan IIS'i kullanmak.

İlgili sınıfı yeni bir thread için de aşağıdaki şekilde çalıştırabiliriz;

  Thread thread = new Thread(MyMethod, 1048576);
  t.Start();

  void MyMethod()
        {
              //Çağrılan sınıf / method
        }




Bu yöntem ile methodun çalışması için 1MB StackSize tanımlamış olduk.
Yalnız buradaki sıkıntı web uygulamalarında yapılan bir isteğin (sayfa veya ajax isteği), bu methodun sonucunu bekleme şansı yok. Thread arka planda çalışacaktır ama kod akışı Start dediğiniz noktadan akmaya devam edecektir.

Diğer alternatif de ise IIS Express'in kullanım kolaylığından çıkıp yerel IIS servisinde çalışabilmesi için diğer tanımlamaları yapmak. Eski sıkıntılı günleri hatırlattı...

Bu durumda problemin çözümü için IIS ve IIS Express'in çalışma mantığı arasındaki farkı bulmak gerekti.

MS tarafından yayınlanan bu makalede .Net uygulamaları için (console, masaüstü, servis...) normalde 1MB  StackSize tanımı olduğunu ama bu Asp.net için farklı olduğunu öğreniyoruz.
Detayında ise 32bit uygulamalarda 256KB, 64Bit uygulamalarda ise 512KB tanımı var.

" In Windows Server 2008 and higher, the maximum stack size of a thread running on 32-bit version of IIS is 256 KB, and on an x64 server is 512 KB."
İlgili makale:
By default, the maximum stack size of a thread that is created in a native IIS process is 256 KB

Diğer bir detay Visual Studio'da IIS Express default olarak 32Bit çalışıyor.
Eğer 512 KB yeterliyse alttaki şekilde Visual Studio da IIS Express i 64 bit olarak kullanmak istediğinizi belirtebiliyorsunuz:

VS 2015 Tools> Options> Projects and Solutions > Web Projects > Use the 64 bit version of IIS Express for web sites and projects

Yetmediği durumda ise aşağıdaki linklerden nasıl arttırılabileceği detayı var.

Ek bilgi:
StackSize belirtmek için alternatif yöntemler ve artıları/eksileri.
http://content.atalasoft.com/h/i/58213648-increasing-the-size-of-your-stack-net-memory-management-part-3
Windows Server 2003 sonrası değişim
http://blogs.msdn.com/b/tom/archive/2008/03/31/stack-sizes-in-iis-affects-asp-net.aspx



Hiç yorum yok: