Sunday, April 18, 2010
What is garbage collection?
Garbage collection is a mechanism that allows the computer to detect when an object can no longer be accessed. It then automatically releases the memory used by that object (as well as calling a clean-up routine, called a "finalizer," which is written by the user). Some garbage collectors, like the one used by .NET, compact memory and therefore decrease your program's working set.
How does non-deterministic garbage collection affect my code?
For most programmers, having a garbage collector (and using garbage collected objects) means that you never have to worry about deallocating memory, or reference counting objects, even if you use sophisticated data structures. It does require some changes in coding style, however, if you typically deallocate system resources (file handles, locks, and so forth) in the same block of code that releases the memory for an object. With a garbage collected object you should provide a method that releases the system resources deterministically (that is, under your program control) and let the garbage collector release the memory when it compacts the working set.
Can I avoid using the garbage collected heap?
All languages that target the runtime allow you to allocate class objects from the garbage-collected heap. This brings benefits in terms of fast allocation, and avoids the need for programmers to work out when they should explicitly 'free' each object.
The CLR also provides what are called ValueTypes—these are like classes, except that ValueType objects are allocated on the runtime stack (rather than the heap), and therefore reclaimed automatically when your code exits the procedure in which they are defined. This is how "structs" in C# operate.
Managed Extensions to C++ lets you choose where class objects are allocated. If declared as managed Classes, with the __gc keyword, then they are allocated from the garbage-collected heap. If they don't include the __gc keyword, they behave like regular C++ objects, allocated from the C++ heap, and freed explicitly with the "free" method.
How do in-process and cross-process communication work in the Common Language Runtime?
There are two aspects to in-process communication: between contexts within a single application domain, or across application domains. Between contexts in the same application domain, proxies are used as an interception mechanism. No marshaling/serialization is involved. When crossing application domains, we do marshaling/serialization using the runtime binary protocol.
Cross-process communication uses a pluggable channel and formatter protocol, each suited to a specific purpose.
If the developer specifies an endpoint using the tool soapsuds.exe to generate a metadata proxy, HTTP channel with SOAP formatter is the default.
If a developer is doing explicit remoting in the managed world, it is necessary to be explicit about what channel and formatter to use. This may be expressed administratively, through configuration files, or with API calls to load specific channels. Options are:
HTTP channel w/ SOAP formatter (HTTP works well on the Internet, or anytime traffic must travel through firewalls)
TCP channel w/ binary formatter (TCP is a higher performance option for local-area networks (LANs))
When making transitions between managed and unmanaged code, the COM infrastructure (specifically, DCOM) is used for remoting. In interim releases of the CLR, this applies also to serviced components (components that use COM+ services). Upon final release, it should be possible to configure any remotable component.
Distributed garbage collection of objects is managed by a system called "leased based lifetime." Each object has a lease time, and when that time expires, the object is disconnected from the remoting infrastructure of the CLR. Objects have a default renew time-the lease is renewed when a successful call is made from the client to the object. The client can also explicitly renew the lease.
Can I use COM objects from a .NET Framework program?
Yes. Any COM component you have deployed today can be used from managed code, and in common cases the adaptation is totally automatic.
Specifically, COM components are accessed from the .NET Framework by use of a runtime callable wrapper (RCW). This wrapper turns the COM interfaces exposed by the COM component into .NET Framework-compatible interfaces. For OLE automation interfaces, the RCW can be generated automatically from a type library. For non-OLE automation interfaces, a developer may write a custom RCW and manually map the types exposed by the COM interface to .NET Framework-compatible types.
Can .NET Framework components be used from a COM program?
Yes. Managed types you build today can be made accessible from COM, and in the common case the configuration is totally automatic. There are certain new features of the managed development environment that are not accessible from COM. For example, static methods and parameterized constructors cannot be used from COM. In general, it is a good idea to decide in advance who the intended user of a given type will be. If the type is to be used from COM, you may be restricted to using those features that are COM accessible.
Depending on the language used to write the managed type, it may or may not be visible by default.
Specifically, .NET Framework components are accessed from COM by using a COM callable wrapper (CCW). This is similar to an RCW (see previous question), but works in the opposite direction. Again, if the .NET Framework development tools cannot automatically generate the wrapper, or if the automatic behavior is not what you want, a custom CCW can be developed.
Can I use the Win32 API from a .NET Framework program?
Yes. Using platform invoke, .NET Framework programs can access native code libraries by means of static DLL entry points.
Here is an example of C# calling the Win32 MessageBox function:
public static extern int MessageBox(int hWnd, String strMessage, String strCaption, uint uiType);
public static void Main()
MessageBox( 0, "Hello, this is PInvoke in operation!", ".NET", 0 );
What do I have to do to make my code work with the security system?
Usually, not a thing—most applications will run safely and will not be exploitable by malicious attacks. By simply using the standard class libraries to access resources (like files) or perform protected operations (such as a reflection on private members of a type), security will be enforced by these libraries. The one simple thing application developers may want to do is include a permission request (a form of declarative security) to limit the permissions their code may receive (to only those it requires). This also ensures that if the code is allowed to run, it will do so with all the permissions it needs.
Only developers writing new base class libraries that expose new kinds of resources need to work directly with the security system. Instead of all code being a potential security risk, code access security constrains this to a very small bit of code that explicitly overrides the security system.
Why does my code get a security exception when I run it from a network shared drive?
Default security policy gives only a restricted set of permissions to code that comes from the local intranet zone. This zone is defined by the Internet Explorer security settings, and should be configured to match the local network within an enterprise. Since files named by UNC or by a mapped drive (such as with the NET USE command) are being sent over this local network, they too are in the local intranet zone.
The default is set for the worst case of an unsecured intranet. If your intranet is more secure you can modify security policy (with the .NET Framework Configuration tool or the CASPol tool) to grant more permissions to the local intranet, or to portions of it (such as specific machine share names).
How do I make it so that code runs when the security system is stopping it?
Security exceptions occur when code attempts to perform actions for which it has not been granted permission. Permissions are granted based on what is known about code; especially its location. For example, code run from the Internet is given fewer permissions than that run from the local machine because experience has proven that it is generally less reliable. So, to allow code to run that is failing due to security exceptions, you must increase the permissions granted to it. One simple way to do so is to move the code to a more trusted location (such as the local file system). But this won't work in all cases (web applications are a good example, and intranet applications on a corporate network are another). So, instead of changing the code's location, you can also change security policy to grant more permissions to that location. This is done using either the .NET Framework Configuration tool or the code access security policy utility (caspol.exe). If you are the code's de
veloper or publisher, you may also digitally sign it and then modify security policy to grant more permissions to code bearing that signature. When taking any of these actions, however, remember that code is given fewer permissions because it is not from an identifiably trustworthy source—before you move code to your local machine or change security policy, you should be sure that you trust the code to not perform malicious or damaging actions.
How do I administer security for my machine? For an enterprise?
The .NET Framework includes the .NET Framework Configuration tool, an MMC snap-in (mscorcfg.msc), to configure several aspects of the CLR including security policy. The snap-in not only supports administering security policy on the local machine, but also creates enterprise policy deployment packages compatible with System Management Server and Group Policy. A command line utility, CASPol.exe, can also be used to script policy changes on the computer. In order to run either tool, in a command prompt, change the current directory to the installation directory of the .NET Framework (located in %windir%\Microsoft.Net\Framework\v1.0.2914.16\) and type mscorcfg.msc or caspol.exe.
How does evidence-based security work with Windows 2000 security?
Evidence-based security (which authorizes code) works together with Windows 2000 security (which is based on log on identity). For example, to access a file, managed code must have both the code access security file permission and must also be running under a log on identity that has NTFS file access rights. The managed libraries that are included with the .NET Framework also provide classes for role-based security. These allow the application to work with Windows log on identities and user groups.