790 likes | 1.03k Views
.Net Architecture. Jon Shemitz Midnight Beach. Introduction. Why people are excited about .Net Three main sections 10% Why .Net? 10% A quick run through the acronyms 80% A more detailed walk up the stack Heavy on machinery, light on code you actually call.
E N D
.Net Architecture Jon Shemitz Midnight Beach
Introduction • Why people are excited about .Net • Three main sections • 10% Why .Net? • 10% A quick run through the acronyms • 80% A more detailed walk up the stack • Heavy on machinery, light on code you actually call
Why .Net? Microsoft’s perspective • The Java threat • .Net is the managed code environment Microsoft needs to compete against Sun in the enterprise arena • Microsoft needs you, the programmer • Network effects give their OS franchise its value • Java has had great success with “Learn once, work anywhere”
Why .Net? Developer’s perspective • Managed code • Makes Other Peoples’ Code more reliable • The run time library is really good • Objects all the way down • Exciting programming environment • Little penalty for very light-weight objects • Deep language neutrality • Where Microsoft adds most value to Java
Why .Net? Delphi perspective • .Net has a lot of the Delphi feel • There are some new ways to code • Garbage collection turns objects into values • Easy for a Delphi developer to learn .Net • Skills transfer, expectations tend to be right • Delphi experience gives you an edge in the .Net world
Java’s good points • The API is object oriented from bottom to top • No alphabetized lists of hundreds of flat function names • Managed code means some common programming mistakes are not possible • This is a security feature, not a Lazy Programmer Convenience - a system without buffer overruns is a safer system
Java is a tough target • Microsoft can’t beat Java with FUD • Embrace And Extend won’t work, either • They had to fall back on Plan C: • Lots of hard work by lots of bright people
Java’s Achilles’ heel is Java itself • The environment is great but you can’t simply port legacy code to Java – you have to rewrite it • Many companies have decades worth of legacy systems • They might port their legacy code to a managed code system, but they won’t rewrite all their legacy code
Language neutrality • .Net offers all the advantages of Java, plus language neutrality. • All .Net languages use the same object-oriented runtime library, the Framework Class Library [FCL] • You’ll have to learn the FCL • Once you know the FCL, you can easily work in whatever language the legacy code du jour was written in
Java + language neutrality • Java and .Net have the same two compelling features: • An object oriented API • A managed code environment • No loose pointers • No memory leaks • .Net adds language neutrality
End of introduction • Key features • Object-oriented API • Managed code • Language neutrality • Next • A bottom-up tour of the architecture • Watch for these features, emerging from the details
Common Abbreviated Names FCL Framework Class Library CTS Common Type System (CLS) Common Language Specification CLR Common Language Runtime
CLR = Common Language Runtime • Garbage collection • Just-in-time compilation • .Net isneverinterpreted • The jitter [the JIT compiler] compiles about as fast as Delphi • The object code that the jitter puts out is a lot like Delphi’s object code • Only better, because the jitter can do function inlining
CTS = Common Type System • Basic value types • Type composition • Type safety • Objects • Interfaces • Delegates • Delegates are a multi-cast version of Delphi’s events
CLS = Common Language Specification • Subset of the Common Type System • All 1st class .Net languages need to support CLS • You can have non-CLS type - like unsigned integers - but some .Net languages won’t understand them • For example, Visual Basic doesn’t have unsigned integers
FCL = Framework Class Library • FCL is new ‘universal’ run-time library • Object-oriented API • Roughly the same size as the Delphi BPL’s • Thousands of CLS-compliant C# classes • Everything from GUI programming to file IO to web services
And now, the details • Any CEOs can leave the room now • .Net has two main parts • Runtime • Written in C++ • Framework classes • Written in C# • Components and applications • Any language
CLR: the .Net engine • Gets threads and memory from the underlying OS, and not much else • Four major components: • Just In Time compilation of CIL [Common Intermediate Language] to native object code • Garbage collection • Common Type System [CTS] • Exception handling machinery
The CLR manages your code • No “tombstoned” pointers; no miscasting • You can never accidentally treat a TFont as a TStringList • Managed code is not interpreted code • .Net maintains type safety and memory safety while running compiled object code
.Net portability? • Porting .Net means porting the CLR • You’d also have to port the WinForms library before desktop (GUI) programs will work • ECMA-335 • 2000 pages that describe core functionality • A very large, multi-year task • ISO standardization • Coming this month
OS/X and Linux • At the May 2002 BorCon, Borland R&D suggested that we’re likelier to see Delphi for .Net running on .Net on OS/X than a native Delphi for OS/X • They also mentioned .Net on Linux as a possible future home for Kylix developers
CIL • All .Net languages compile to CIL • CIL was once known as Microsoft Intermediate Language, or MSIL • A compiled .Net program is called an assembly • An assembly is a standard PE [Portable Executable] exe or dll • Assemblies contain a special header that says that the PE file contains CIL and .Net metadata instead of normal object code
Stub code • Each entry point in the PE file points to stub code • Executing the stub code compiles the CIL to actual object code on an as-needed basis Before JIT After JIT Stub code Object code CIL
JIT overhead • First call is slower than subsequent calls, but not much • CIL is close to machine language • Jitter doesn’t have to handle parsing, linking, or macro expansion. • JIT cost is a relatively modest ‘tax’ on top of demand-load cost
JIT benefits • The jitter can generate object code optimized for the machine it’s running on • In a sense, the jitter is a smart linker • Unused code is not jitted, may not be loaded • So it doesn’t cost time or memory at runtime
A little about CIL • CIL is a sort of p-code • Assemblies store CIL as byte codes • Tokenized assembler that the jitter can compile quickly • The (free) .Net SDK includes the ILASM assembler and the ILDASM disassembler
CIL is a high-level assembly language • Not a Lowest Common Denominator language • No one language uses all CIL features • Has features, like tail recursion, that are used by languages that aren’t even supported yet • CIL is an intermediate language • Compiled at runtime • Not executed directly
CIL is strongly typed • CIL is verbose and strongly-typed - yet CIL is also stack-based and generic • Push Integer and Push Float instructions will fail if the value to be pushed is of the wrong type • Add instruction operates on the two values on the top of the stack and does type conversion as necessary
CIL is easy to write • It’s easier to emit CIL than it is to generate x86 object code • Great for things like spreadsheets, query engines, and script languages • Stack model means that you never have to worry about register allocation • RPN [Reverse Polish Notation] syntax is easy to generate mechanically
System.Reflection.Emit • Applications can use the “reflection” API to emit CIL at runtime • Generated code will be jitted when called, just like any other CIL code
What about garbage collection? • Typical programmer reactions to .Net • “What makes this any better than Java?” • Language neutrality • “But, what about that JIT overhead?” • It’s just not that bad • “Garbage collection sucks.”
Garbage collection doesn’t suck • Many nice features • Fast allocation • Just advancing a pointer, not updating a linked list • Better cache performance • Consecutive allocations are adjacent • Smaller, simpler, and more reliable code • More object-oriented, without ownership issues • No dangling pointers • Data structures never refer to memory that’s been freed
Better than reference counting • Delphi’s strings, dynamic arrays, and interfaces use reference counting • Offers same simplicity and safety as garbage collection but: • Overhead of maintaining the reference counts • Reference counting can’t handle circular references
Garbage collection speed • ‘Old-school’ garbage collectors could lock the system unpredictably • Canceled advantages of garbage collection • Lead to bad reputation • A full .Net garbage collection takes less time than a page fault • Which you typically don’t even notice
Why so fast? • Memory life spans are distributed according to a power law • Most memory is freed quite soon after it’s allocated • Most of what’s left is freed within seconds or minutes • And most of what lasts longer than that lasts until the program shuts down
3 generation garbage collector • Garbage is collected after ‘enough’ allocations • Not only when heap is exhausted • Gen 0 defaults to size of the CPU’s Level 2 cache • Looks at recent allocations • Finds memory blocks that are still in use • “Garbage collection” is a bad name • Only have to do work on blocks that aren’t garbage
Live blocks • Get moved and promoted • The next collection at old level won’t look at them Before generation 0 garbage collection Generation 0 Generation 1 A B C D E F G H I J K free After generation 0 garbage collection Generation 1 A B C D F G J free
Generations 1 and 2 • Generation 1 collection after ‘enough’ more allocation • Finds blocks that not have become garbage since being promoted • Power law at work again – most have died • Survivors are moved and promoted - aren’t touched again until generation 2 garbage collection • Generation 2 garbage collection just moves survivors - does not promote
Generations save work • Cuts times a long-lived object is detected and moved • Speeds live block detection • Walks reference chains down from “roots” • .Net has type data for every structure in the system. It knows every field of every structure. • Walk can stop on old objects: eg, most generation 1 objects only refer to generation 1 or 2 objects, which a generation 0 sweep doesn’t care about • JITter maintains a ‘dirty bit’
Resource protection • Reference counting is slower than garbage collection • But reference counting is better at resource protection • Close file, or restore visual, at moment interface variable goes out of scope and object is freed
Finalization • Finalization routine gets called when the block is scavenged • No control over when it happens • A whole class of “failsafe” Delphi techniques that rely on interface finalization are invalid under .Net
Weak references • Data you don’t currently need that’s relatively expensive to regenerate • Useful for browser cache, or singleton objects like the Printer or Clipboard • “Target” property contains valid reference or Nil • Casting non-Nil Target gives normal (strong) reference that will keep the data from being garbage collected • Just like Java
Safe code • .Net protects you from sloppy code • Managed code eliminates the risks from prematurely released memory and careless casts • Exceptions keep code from assuming a system state that it hasn’t actually attained • .Net also protects you from malicious code • Can peverify code before using it
Exceptions are builtin • Very familiar to Delphi programmers • Lets you assume that each operation will succeed - chains of operations become simpler and clearer • Failed operations jump straight to error handlers, so there’s no risk of acting as if an operation succeeded when it actually failed • CLR supports exceptions • Can’t hose Windows by drawing on a DC that wasn’t really created - exception on canvas creation jumps around actual drawing code
CLR wrapup • CLR manages memory and code • Also supports language neutrality • CTS [Common Type System] is part of the CLR • CTS is basis for language neutrality
Common Type System • Key to managed code, garbage collection, and language inter-op • All .Net languages understand each other’s data types • All use the same primitive types • Record and object definitions are part of the metadata in each assembly
CLS • Common Language Specification • A Visual Basic class can inherit from a C# class that inherits from a Delphi for .Net class • The equivalents of is and as will work just as they should, in all three code-bases • It’s like a cross-language version of packages
Objects are primitives • The CTS provides value types - scalars and records - and objects, and the ability to form composite types from the primitives • Objects are primitives, built into the lowest levels of the system • There’s no sense in which they’re something layered onto a flat API
.Net object model • A lot like the Delphi object model • All objects descend via single-inheritance from a single root object, System.Object • Support for properties, events, and interfaces • Boxing and unboxing • A System.Object can hold any value • Great flexibility • Still type safe – just a lot less busy work • Like variants, but cleaner
Delphi objects • In Delphi for .Net, TObject will be an alias for System.Object • Otherwise, TComponent wouldn’t be a System.Component, and Delphi components couldn’t play in the common language space • But they are not equivalent • TObject has no ToString() • System.Object has no ClassName