Alik Levin's

Clarity, Technology, and Solving Problems | PracticeThis.com 

October, 2008

  • Alik Levin's

    Complex Enterprises And Simple Architectures

    • 1 Comments
     Alik Levin    I started to read a book by Roger Sessions - Simple Architectures for Complex Enterprises. I was intrigued by the title. The number of pages made me completely curious - ~170 pages. First too pages of read made me fall in love with it. I am still reading it but I can surely tell you - it helped me to feel very confident with what I kept to myself so far deep inside.

    I can say it out loud now - "Software architectures are way too complex. And it should not be THAT way".

    Three Basic Problems With Existing Architectures

    Roger shares his experience and give his angle on why the software architectures fail. He writes:

    "First, existing approaches are too expensive to execute. Second, they take too much time to complete. Third, there is no way to validate their results."

    Five Things To Make Enterprise Architecture Right

    Roger provides an insight on how he thinks the enterprise architectures should be  built the right way, he writes:

    "First, we define what we mean by a good enterprise architecture. Second, we use this definition to build up a mathematical model for what a good enterprise architecture looks like. Fourth, We create a process for developing a good enterprise architecture based on that model. Fifth, we validate our resulting architectures against the model  before we implement them"

    Definition of Good

    Rogers give pretty simple of definition of the good enterprise architecture, he writes:

    "Of two architectures that generally align to business needs and IT capabilities, the better of the two is the simpler of the two. The worst of the two the one is more complex."

    Simple, no? ;)

    Customer Case Study #1

    While the context is about enterprise architecture I am sure one can extrapolate the main principles to solution architecture. Here is the case I was involved. The customer implemented distributed solution. The solution included each and every possible MS technology and products. I was called to provide my insights about why the solution performs poorly. I was way to proud they use our technology, but they took it way too far beyond the guidelines. I told them the truth "It is way too complex". I was moved to another project shortly. No regrets. While it could be pure career blocking move - I've chosen to stick with my engineering values.

    Customer Case Study #2

    Another customer implemented a brand new Internet facing flagship web site. It was developed as a plain vanilla, blue print based web site (as depicted in the Architecture part). The project hit the dead line. It was implemented on budget and on features. When the problems occurred. It was easy to investigate and fix it. Period.

    Consultant's Dilemma

    There is eternal dilemma I cope with. A customer is excited about using one or another MS feature/technology/product. I am asked what would I recommend. I know I want to say "No" since using it would add more complexity to the project on one hand. But I need to be a good MS citizen on other hand. What should I do? I usually walk the customer through the process of implementing and maintaining it using the technology. I am trying to make sure the customer is aware of the risks. After that the customer should make a better decision.

    • What would you do?
    • What's your take on complexity/simplicity of enterprise/software architecture?

    Related Materials

    This template is made with PracticeThis.com plugin for Windows Live Writer

  • Alik Levin's

    ASP.NET Performance: Dynamically Loaded Assemblies Cause Application Recycles (Problem and Solution)

    • 4 Comments
     Alik Levin    In my speak - dynamically loaded assemblies are those assemblies that were compiled during run time dynamically via CodeProvider like CSharpCodeProvider directly or by using types that use this class internally. Assemblies that are loaded dynamically using reflection via Load/LoadFrom method are out of the scope of this post.

    Customer Case Study

    The customer complained on periodic restarts/recycles of the ASP.NET application. We observed relative entries in the Event Log that showed up systematically on timely basis. We also observed memory utilization growth in Task Manager. After reaching 500 MB of memory utilization the application would recycle spawning another w3wp.exe to accept new incoming requests while draining the old w3wp.exe.

    Analysis

    After short discussion with the dev team about the design of the application we thought that the memory leak might be caused by improper usage of XmlSerializer that generate dynamic assemblies. Tess published fantastic walk through specifically dedicated to this case. Using either perfmon (.NET CLR Loading\Current Assemblies) or Process Explorer (see pic below)we observed unusual number (thousands) of loaded assemblies (notice Assemblies column). Also, notice the csc.exe in red - this is CSharp compiler that is invoked on each request:

    Process Explorer ASP.NET Performance Dynamically Loaded Assemblies

    We decided to take a memory dump to deeply investigate the case. Following are the steps that we took while analyzing the dump using WinDBG to identify the root cause:

    Step 1 - Dumping memory heap to identify object allocated on heap

    This is the fragment of the long list of objects. Our attention was caught by unusually large number of reflected assemblies.

    !dumpheap –stat
    9,019       216,456 System.Reflection.Assembly
    112         4,032 System.Xml.Serialization.TempAssembly
    104         5,408 System.Xml.Serialization.TypeDesc

    After 3 minutes the number of dynamic assemblies is larger by more 350 assemblies (from subsequent dump):

    !dumpheap –stat
    9,379       225,096 System.Reflection.Assembly
    114         4,104 System.Xml.Serialization.TempAssembly
    102         5,304 System.Xml.Serialization.TypeDesc

    Step 2 - Dumping appdomains to identify loaded assemblies

    Another cross check to make sure we are dealing with tons of loaded assemblies.

    !dumpdomain -stat 
        Domain              Num Assemblies   Size Assemblies    Name
    0x793f15d8                       1                       2,142,208        System Domain
    0x793f2aa8                       56                    16,012,288      Shared Domain
    0x000ab7d8                      2                       2,498,560        DefaultDomain
    0x000d3368                  9,018                  55,447,040      /LM/W3SV......

    Total 4 Domains, Total Size 76,100,096

    Step 3 - Dumping all dynamic assemblies

    How many of the assemblies are dynamic? (dda stands for dumpdynamicassemblies)

    !dda

    Domain: 0x793f15d8
    -------------------
    Domain: .
    -------------------
    Domain: DefaultDomain
    -------------------
    Domain: /LM/W3SVC/1/ROOT/......
    -------------------
    Assembly: 0x19058818 [RegexAssembly133_0] Dynamic Module: 0x16f4c220 loaded at: 0x0 Size: 0x0((null))
    Assembly: 0x19058818 [RegexAssembly133_0] Dynamic Module: 0x190696a0 loaded at: 0x0 Size: 0x0((null))
    Assembly: 0x19103ee8 [-0g5u8-v] Dynamic Module: 0x1920d6f8 loaded at: 0x19911000 Size: 0xc000((null))
    Assembly: 0x190c9a40 [cvmmynwf] Dynamic Module: 0x190dc0d0 loaded at: 0x19a71000 Size: 0x4000((null))
    Assembly: 0x1911bad8 [0ikhy_lx] Dynamic Module: 0x1911aa98 loaded at: 0x19f21000 Size: 0xc00((null))
    .......
    Assembly: 0x43199720 [nv1lvdiy] Dynamic Module: 0x431b3190 loaded at: 0x4cf61000 Size: 0xc00((null))
    Assembly: 0x2d2bf008 [rk6dabem] Dynamic Module: 0x2d2bf258 loaded at: 0x4cf71000 Size: 0xc00((null))
    --------------------------------------

    Total 8,911 Dynamic Assemblies, Total size: 0x1d5b600(30,782,976) bytes.

    Step 4 - Saving dynamic assembly to physical DLL

    Save assemblies to the filesystem

    !savemodule 0x2d2bc4c8 C: \0x1c344438.dll

    clip_image002

    To save all the assemblies to the file system use the following command:

    !dda -save C:\MODULES

    Step 5 - Using Reflector to reverse engineer the DLL:

    Use Reflector to inspect the implementation/source code of the dynamic assemblies.

    clip_image001

    Step 6 - Using Reflector to find  ExpressionEvaluator class

    Try to locate the class in the static assemblies hopefully hitting the code that generates it:

    image

    Step 7 - Bingo! Each constructor for ExpressionEvaluator invokes compiler

    ICodeCompiler compiler = new CSharpCodeProvider().CreateCompiler();
    ...
    CompilerResults results = compiler.CompileAssemblyFromSource(options, builder.ToString());
    ...
    this._Compiled = results.CompiledAssembly.CreateInstance("NavServices._ExpressionEvaluator");

    This is actually the code that causes Process Explorer to show csc.exe under w3wp.exe (see red line in the first pic). And this is the code that caused number of loaded assemblies to grow. And this is the code that caused the application restarts.

    Acknowledgements

    During this investigation the following resources were used. Big THANK-YOU goes to:

    Related Materials

    This template is made with PracticeThis.com plugin for Windows Live Writer

  • Alik Levin's

    Improve ASP.NET 2.0 Performance With PageAsyncTask - Multithreading For The Masses

    • 0 Comments
     Alik Levin    Multithreading is tough. This is what John Robbins says about it in his excellent book Debugging Microsoft .NET 2.0 Applications:

    "Don't do it... Make sure there's no other way you can structure your program before you decide to incorporate multithreading into your application... you are easily adding a minimum of an extra month of development and testing to your schedule". I agree with it completely. But there are times multithreading is unavoidable. Especially when more and more Services popping up in the wild...


    From Asynchronous Pages in ASP.NET 2.0

    Customer Case Study

    I am working with the customer to improve their ASP.NET 2.0 application performance. The application issues multiple requests to the backend middleware that is exposed as a web service. The application cannot get a hold on the actual proxies rather it is provided with the components that wrap the web services proxies. The application needs to issue concurrent  requests. Serial request would result in serious latency which is unacceptable by end users.

    Analysis

    Since we cannot get hold on web services proxies we cannot utilize available asynchronous methods available with it: BeginMyMethod/EndMyMethod and MyMethodAsync/MyMethodCompleted. But we definitely can utilize another option available with ASP.NET 2.0 - registering asynchronous tasks using PageAsyncTask class.

    The following information is based on the following materials:

    PageAsyncTask Implementation Steps

    This is the summary of the steps to implement and register PageAsyncTask:

    • Create a class that contains lengthy operation
    • Declare AsyncTaskDelegate
    • Add OnBegin, OnEnd, OnTimeout methods to the class
    • Mark the calling page as Async="true"
    • Register the PageAsyncTasks in the ASPX page and execute it

    You can grab the Visual Studio 2008 project with the implementation from my SkyDrive here:

    Related Materials

    This template is made with PracticeThis.com plugin for Windows Live Writer

Page 2 of 2 (6 items) 12