550 likes | 1.02k Views
Microsoft .NET Framework: CLR Futures. Working better togeth er , faster, with fewer bugs. Joshua Goodman Group Program Manager Microsoft Corporation. Introduction. CLR 4.0: our largest release since 2.0. 3.5. 3.0. .NET 1.0. .NET 1.1. .NET 2.0. .NET 4.0. 2002. 2003. 2005.
E N D
Microsoft .NET Framework:CLR Futures Working better together, faster, with fewer bugs Joshua Goodman Group Program Manager Microsoft Corporation
Introduction CLR 4.0: our largest release since 2.0 3.5 3.0 .NET 1.0 .NET 1.1 .NET 2.0 .NET 4.0 2002 2003 2005 2005-08 2008 CTP!
Quick Reminder – What Is The CLR WPF Win Forms DLR Dynamic Language Runtime ASP. NET WCF LINQ And more! The CLR Base Class Libraries Profiling& Debugging APIs JIT & NGEN Garbage Collector Security Model Exception Handling Loader & Binder
Outline • Working Better Together • In Process Side X Side • Native/Managed Interop • Dynamic and Functional Languages • Faster • 3.5 SP1 improvements • Threading • Garbage Collection • Profiling • With fewer bugs • Corrupted State Exceptions • Debugging • Code Contracts
Working Better Together: Overview • In Process Side X Side • How the CLR works better with itself • No PIAs • Working better with COM objects • Native wrapping tool • Working better with Windows APIs • Support for Dynamic and Functional Languages: • Languages working with each other
In Process Side By SideThe CLR, working with itself • Quick overview • Why it’s so hard to be highly compatible • In Process Side by Side –multiple CLR versions working together
Why High Compatibility Is So HardA very sad story • .NET Framework 1.1 was highly compatible with 1.0 Thread [] threads = new Thread[8]; for (inti=0; i<8; i++) { Worker worker = new Worker(); threads[i] = new ThreadStart(worker.Work); threads[i].Start(); worker.identity =i; } Code from an Outlook addin our executives used
Why High Compatibility Is So HardA very sad story – continued • .NET 1.1 just slightly faster for starting threads • No Executives at Microsoft could use their mail • Bug wasn’t our fault – but no one cares Thread [] threads = new Thread[8]; for (inti=0; i<8; i++) { Worker worker = new Worker(); threads[i] = new ThreadStart(worker.Work); threads[i].Start(); worker.identity =i; } Code from an Outlook addin our executives used
The Layercake Model • Side X Side releases solve app compat issue • COM objects and other addins for different layers of the same cake can easily live together on the same runtime • Highly compatible – but only certain kinds of functionality can be added 3.5 3.0 .NET 1.0 .NET 1.1 .NET 2.0 .NET 4.0
New In Process Side By Side ModelHave your cake and eat it too • Configuration file and hosting APIs give you fine grained control • For both applications and COM, a config file describes which versions you run on, and which you prefer i 2.0 addin 3.0 addin 3.5 addin 4.0 addin • Run both 2.0-based and 4.0-based CLR in the same process • Old components use old CLR • New components use new CLR 3.5 .NET 4.0 3.0 .NET 2.0 Host Process (e.g. Outlook)
New Host API • New Interfaces: • ICLRMetaHost; • ICLRMetaHostPolicy; • ICLRRuntimeInfo; • ICLRRuntimeHost3; • ICLRStrongName • Legacy Static Global Hosting Functions will be marked as deprecated
Exposing a Native App to ManagedExperience Today • Run TLBIMP -> Generates an interop assembly • Fix it: Run ILDASM; Hand modify IL or write jscript; Run ILASM • Designate assembly as a PIA • Deploy it • Include with your native app • What if you don’t pre-req .NET? • Every addin brings a big (5 MB?) PIA along • Move to V2 of your app • Update your jscript • Make sure everyone brings the new PIA; create publisher policy
Exposing a Native App to ManagedExperience With .NET 4.0 • Get our TLBIMP shared source from Codeplex; modify it if you need to • Easier than postprocessing with jscript • Biggest improvement is deployment experience • At compile time we consume new Interop Assemblies and pull in the referenced types to local definitions. • Pull in *only* the methods that are used. • New [TypeIdentity] attribute, we can maintain type equivalence in the CLR by respecting the GUID (or other arbitrary string)
Wrapping Tool • New tool reads in windows.h and SAL annotations • Outputs p/invoke wrappers • Calling native Windows code has never been easier.
.NET And Managed LanguagesIntroduction • It’s been a great platform for multiple languages since the beginning • 16 languages at launch • Some languages hard – dynamic and functional languages • Now releasing IronPython, IronRuby, F#, and other languages • Tuples • BigInteger • Tail recursion
What Did The CLR Team Have To Do?Not much • If the CLR is really already general purpose, shouldn’t have to do much to accommodate a new language • We didn’t! • Rare instance in which doing only a little work is a good thing • Overview • Big Integer • Tuples • Tail Recursion
BigIntegers • Request from both F# and Python • Fast: Optima Team “Microsoft Solver Foundation” helped us • All languages benefit; libraries can interoperate.
Support For F# and Python: Tuples • Tuples are a construct used in F# and Python – classes created on the fly • How to make a class in F# or Python. (4, “Hello World”) • In BCL to allow interoperation of libraries • Subtle issues, e.g. equality, • Example: remember that NaN == NaN is false • Hard to get the right behavior in each language, while still allowing sharing across languages – but we did it!
Bonus: Tuples Now Convenient In C# • Tuples supported natively in F# and Python, but also easy to use now from C#, etc. • All languages benefit from CLR’s cross language philosophy publicTuple<Int32, Int32> DivAndRemainder(Int32i, Int32 j) { returnnewTuple.Create(i/j, i%j); } // An example of someone accessing items in a tuple. for (Int16i = 0; i <= 25; i++) { for (Int16j = 1; j <= 5; j++) { vartuple = DivAndRemainder(i,j); Console.WriteLine("{0}\t{1}\t{2}\t{3}\n", i, j, tuple.item1, tuple.item2); }
Support For F# – Tail Recursion • F# is a new functional language designed for .NET (related to OCaml, and ML) • Functional languages discourage assignment • Example let rec Factorial n = match n with 1 -> 1 | _ -> n * Factorial (n - 1) Under the covers, compiler can convert this into a loop, like this C# code: int product = 1; for (int i=n; n>=1; n--) { product = product * n; } This is called “Tail Recursion Optimization.” Because this is so common in F#, we needed to make sure we caught some cases that were being missed in the 64 bit compiler.
.NET and Managed LanguagesSummary • Original promise of the CLR was as a platform for multiple languages • Original .NET included 16 languages • Now expanding that original promise, proving the power of the platform • New language classes – dynamic languages (IronPython, IronRuby) and Functional (F#) • Improvements for these languages get pushed back into the platform, preserve the original promise of cross-language sharing
Working Better TogetherSummary • In Process Side by Side lets the CLR work with itself • High compatibility, while exposing new features • No PIAs makes it easier for managed apps to call native, easing interop assembly generation and deployment • Native wrapping tool makes it easier to work with Windows • Support in BCL for BigInteger and Tuples preserves interop across languages
FasterOverview • 3.5 SP1 Improvements • Faster install, faster startup • Threading Improvements • Faster parallel code • GC notification and Background Collection • Reduce latency • Profiling improvements • Help you write faster server code
Client ProfileFaster install and Startup • Vista: 3.0 is installed; 3.5SP1 coming • No install needed! • XP boxes with 2.0 or above will also get 3.5SP1 via Windows Update • What about XP boxes without 2.0? • 200K bootstrapper, 25 MB download • Great Installer • Customizable, branded experience • Downloads, installs, and NGENs in parallel – takes a few minutes • 3 clicks to app – 1 for exe; 1 for cert; 1 for EULA • Faster startup
Digression:3.5SP1 Other Improvements • More Good Stuff • Run from network share with full trust • Faster WPF (more in hardware), More WinForms controls, Lots of ASP.NET improvements, Visual Studio Improvements for HTML, JavaScript, more • Summary • Now more scenarios where you can use the .NET Framework
Parallel and Threading • Parallel.For(0, n, i => work(i)); • Parallel.ForEach(data, e => work(e)); • var results = from item in shows.AsParallel() • where item.Description.Contains(keyword) && • item.Year > startYear • orderbyitem.StartTime ascending • select item; • Fantastic new features make it very easy to write parallel/multi-threaded applications • Take advantage of multi-core
Parallel and Threading • Parallel.For(0, n, i => work(i)); • Parallel.ForEach(data, e => work(e)); Parallel features are built on top of our existing thread-pool • Manually created threads and Task Parallel Library (Parallel.For) threads share same library • How many threads to create? If lots of cores; lots of threads; if lots of blocking, even more threads; too many threads leads to contention • Sophisticated new algorithm built in cooperation with parallel framework team leads to better performance – for all threads.
Quick Garbage Collection Review • Generation 0 and 1 collections are fast – ephemeral segment is small. Generation 2 collection can be relatively slow. • Today, there can be noticeable pauses, on both server and client (“workstation”) when Gen2 is large. • CLR 4.0 addresses both server and workstation, in different ways. • Server Solution: Gen 2 notification • Workstation Solution: New Background Collection feature Ephemeral Segment Other Segments Generation 0, 1 and parts of Generation 2 live here Most of Generation 2 lives here
Server Garbage Collection Server Garbage Collection • Algorithm maximizes overall throughput – fast – but all managed code has to be paused while it runs.. • In CLR 4.0, you can be notified before a Gen 2/ Large Object Heap collection. • Useful when you can do load balancing. Ephemeral Segment Other Segments Ephemeral Segment Other Segments Ephemeral Segment Other Segments Generation 0, 1 and parts of Generation 2 live here Most of Generation 2 lives here
Sample code public static voidMain(string[] args) { try { // Register for a set of notifications. // Parameters require tuning. First is // for Gen2, second, Large Object Heap GC.RegisterForFullGCNotification(10, 10); // Start a thread using WaitForFullGCProc Thread thWaitForFullGC = newThread(new ThreadStart(WaitForFullGCProc)); thWaitForFullGC.Start(); } catch (InvalidOperationExceptioninvalidOp) { Console.WriteLine("GC Notifications are not supported while concurrent GC is enabled.\n” + invalidOp.Message); } } public static void WaitForFullGCProc() {{ while (true) { // Wait for a notification GCNotificationStatus s = GC.WaitForFullGCApproach(); if (s == GCNotificationStatus.Succeeded) { // This call will direct new traffic // away from machine; wait for old // traffic to finish; then call //GC.Collect() OnFullGCApproachNotify(); } // Wait for a notification of completion s = GC.WaitForFullGCComplete(); if (s == GCNotificationStatus.Succeeded) { OnFullGCCompleteEndNotify(); } } }
New Background CollectionWorkstation solution • “Workstation” (client) collection in 3.5SP1 and earlier uses “Concurrent Collection.” • Can do most, but not all, of a Generation 2 collection without pausing managed code • New allocations go on ephemeral segment • But can’t do Gen0 and Gen1 at same time as Gen2. • New in CLR 4.0, we have Background Collection • Background Collection can do a Gen0 or Gen1 while doing Gen2 • Only unusual circumstances now lead to long latency Ephemeral Segment Other Segments Generation 0, 1 and parts of Generation 2 live here Most of Generation 2 lives here
Latency in Background GC vs. Concurrent GC flavors Concurrent GC Raw latency in microseconds Profiling samples of latency during application execution Background GC
Profiling • Ability to attach and detach performance and memory profilers • CPU sampling • Real-time heap analysis and object reference graphs* • No-impact deployment of tools • No need to set registry keys
FasterSummary • 3.5 SP1 Improvements • Client profile installs quickly, starts faster • Threading Improvements • Faster code, whether using parallel or spawning your own • GC notification and Background Collection • Fewer long pauses • Profiling improvements • Help you write faster code, particularly on the server
Fewer BugsOverview • Corrupting state exceptions • Harder to make a common mistake • Support for dump debugging • Use the tools you already know for dumps • Code Contracts • Cutting edge code analysis
Bad and all too common pattern public void FileSave(String name) { try { FileStreamfs = new FileStream(name, FileMode.Create); } catch(Exception e) { MessageBox.Show("File Open Error"); throw new Exception(IOException); }
Bad and all too common pattern public void FileSave(String name) { try { FileStreamfs = new FileStream(name, FileMode.Create); } catch(Exception e) { MessageBox.Show("File Open Error"); throw new Exception(IOException); } • What if Exception is A/V Exception, Illegal Instruction, or other exception indicating process state is corrupt? • Best thing to do is to get out fast, before persistent data is corrupted, or more work is lost.
Corrupted State Exceptions • New concept in CLR 4: Corrupted State Exceptions • Cannot be caught by normal catch statements. • Examples: A/V Exception, Invalid Memory, Division by Zero, Stack Overflow • But you might want to catch these: • In main: write to log file, exit, perhaps turn off an addin on next run • Very rare cases when you know code throws an exception that isn’t dangerous • [HandleProcessCorruptedStateExceptions] attribute (code must be SecurityCritical – not sandboxed) • Process-wide compat switch: legacyCorruptedStateExceptionsPolicy (=true/false)
Debugging • Dump debugging support via ICorDebug • Same API that is used to enable live debugging • Support for Windows Error Reporting mini-dumps
Debugging • Yes, 64-bit mixed-mode supports live and dump debugging as well • Lock inspection APIs • What object is holding a lock? • Who’s waiting for it?
Code Contracts You know a lot about your code • Some argument to a method is never NULL, other bad inputs • Return value properties Today, very few ways to tell the computer what you know, have it help look for errors • Assert statements • Some third party tools that can handle some special cases, like “Null” Cool new bleeding edge stuff
Example public void BuyMoreStuff(Item[] cart, ref Decimal totalCost, Item i) { CodeContract.Requires(totalCost >=0); • CodeContract.Requires(cart != null); CodeContract.Requires(CodeContract.ForAll(cart, s => s != i)); CodeContract.Ensures(CodeContract.Exists(cart, s => s == i); CodeContract.Ensures(totalCost>= CodeContract.OldValue(totalCost)); CodeContract.EnsuresOnThrow<IOException>(totalCost== CodeContract.OldValue(totalCost)); • // Do some stuff • … • }
Conclusion – Part 1 • Working Better Together • In Process Side X Side • Lets you safely use new stuff on existing machines • Native/Managed Interop • Easier to expose native code to managed • Dynamic and Functional Languages
Conclusion – Part 2 • Faster • 3.5 SP1 improvements • Easier to get installed on client, faster client startup • Threading • Multicore machines • Garbage Collection • Reduces latency on the client and the server • Profiling • Fast apps in the data center
Conclusion – Part 3 • With fewer bugs • Corrupted State Exceptions • Debugging • Dump debugging • Code Contracts • Find bugs with static analysis; more powerful run time checks
Learn More • Research: Contract Checking and Automated Test Generation with Pex • Presenter(s): Mike Barnett, Nikolai Tillmann • Managed and Native Code Interoperability: Best Practices • Presenter: Jesse Kaplan • Advances in .NET Type System • Presenter: MishaShneerson • Microsoft .NET Framework: Overview and Applications for Babies • Presenter: Scott Hanselman