I was recently working on an application loading a big object using a custom formatter. A simple question came up: how big is this object in memory? It is clear that sizeof does not work. What are the alternatives?
The first one is to use Visual Studio 2008 Profiler and see how big are every object of the application. Since my application is pretty big, it could take long time before I have the full profile. I needed a simpler and faster way to measure the memory of that single object.
What about WinDbg and SOS extensions? I verified the symbols path were set in my Visual Studio environment and set a breakpoint at the line the object were created. Then from the immediate window I loaded SOS extensions and started looking at the statistics of all objects loaded in the managed heap:
!dumpheap -stat
The output of the above command provides the list of managed objects without considering the the inner objects. But that list provides also the methods table from which I can get the addess of the object I am interested on:
!dumpheap -mt 0x...
Finally I can get the real size of the object:
!objsize 1dd7a55c
Mission accomplished!
Buck posted a new cool update of the Power Tools for Visual Studio 2005 (Team Test and Team System) and Team Foundation Server.
Just a little note: "Unlike the test container feature, the test category feature will not be in Orcas (if you'd like to see it in a future release, be sure to let these folks know)."
Visual Studio Team Test provides a set of asserts through three classes: Assert, StringAssert and CollectionAssert (all defined in Microsoft.VisualStudio.TestTools.UnitTesting namespace). All of them contains a long list of static methods to test several different kind of data in different ways.
Even if there is a huge number of methods, there are many scenario that aren’t still covered. Let's see a simple example. We need to test if two instances of the same class are equals (contains the same data). Let's see the basic class:
public class MyClass
{
public MyClass(int intProp)
{
this.intProp = intProp;
}
public int IntProp
{
get { return intProp; }
set { intProp = value; }
}
private int intProp;
}
Here is our test case:
Assert.AreEqual(new MyClass(12), new MyClass(12));
Executing the above test we will get a failure: "Assert.AreEqual failed. Expected:<MyLib.MyClass>, Actual:<MyLib.MyClass>".
Why they aren’t equals? We are comparing tow different pointers, simple! Ok, but this isn’t the subject of the post, so, I’ll go ahead.
In order to make the test case succesfull all you need to do is to override the method Equals in MyClass:
public override bool Equals(object obj)
{
if (!(obj is MyClass))
return false;
return ((MyClass)obj).intProp == intProp;
}
I execute again and it works. Is this enough? Not really. Lets consider another test case:
Assert.AreEqual(new MyClass(14), new MyClass(12));
The test will fail as expected producing the following error message “Assert.AreEqual failed. Expected:<MyLib.MyClass>, Actual:<MyLib.MyClass>.”
Not really clear what’s wrong here. We would have some more clear idea of what are the differences, since we are testing with Assert.AreEqual. The idea is to implement a custom assert. An assert class is nothing more than a class with a bunch of static methods that checks the parameter values. If something is not correct (assertion not satisfied), they throws an exception (AssertFailedException). So, in our basic sample we would have something like:
public class MyClassAssert
{
public static void AreEqual(MyClass expected, MyClass actual)
{
Assert.IsNotNull(expected);
Assert.IsNotNull(actual);
if (expected.IntProp != actual.IntProp)
{
throw new AssertFailedException(
string.Format(
"MyClass.IntProp values are different.{0}Expected: {1}, Actual: {2}",
Environment.NewLine,
expected.IntProp,
actual.IntProp));
}
}
}
Applying the above assertion to our test case:
MyClassAssert.AreEqual(new MyClass(14), new MyClass(12));
We will get a more clear error message:
"MyClass.IntProp values are different.
Expected: 14, Actual: 12"
Ok, the sample is super simple and it doesn’t make too much sense, but it give an idea of how to implement custom assertions for more complex ‘real’ types providing meaningful test messages.
UID (unique identification) generation is a really hot topic. It can be really simple as well as really complex. Before going deep in the subject let’s do a couple of simple samples.
To identify a person (citizen) you usually use the SSN (Social Security Number). Isn’t it true? Not at all, because if I don’t consider the domain, the above assertion is completely false. In fact, the SSN is used only in US. So, the SSN is a valid ID for US citizens but not for Chinese, Indians or anyone else.
If I want to identify a record in a table (relational database) I usually use a primary key, which can be simple or composed. But that key is valid only in the domain of the single table. It is pretty guaranteed that we can have another key value in some other table or database.
So, to generate a UID it is really important to try to follow some principles:
- The UID must be system wide unique (pretty obvious)
- The UID should be human readable
- The UID generation must be performing
- The UID must be durable
- The UID must be strongly typed
The first point is not really important if we are talking about a private system/application. Let’s consider the primary key used in the database for DB optimization purpose. If the key is a private stuff of the database/application, integer IDs works very well. But as soon as they become exposed to the public we start having some problems.
Point 2 is really important for debugging, troubleshooting and human interaction. Think about the IP address, people prefer to use the DNS. Easier and clearer than the IP address.
Point 3 is important for scalability. Some applications need to generate thousands of IDs per second, and we cannot have an algorithm that takes seconds to generate an ID. Think about the ID generated for the lottery transaction system.
Point 4 is important for the history. When I lived in Italy I discovered that the Telecom used to re-assign the same phone number after 6 months it has been discontinued. The result was that I received phone calls for scheduling dentist appointments. Reusing an ID is not a good think
Point 5 is important for developers, to guarantee the ID is correctly implemented and used. If you consider an ID as a string, who can guarantee you are not generating a numeric ID (converted to string) and on the other side expecting that ID to be a GUID? Only at runt-time you can discover such problems.
There are good sample of IDs that can match most of the above points, but it is less common to find ID generation that satisfy all of them. For example GUIDs (Global Unique Identifier) satisfy at least point 1, 3, 4 and 5. But they are not human readable (at least to me).
The Xml Schema ID can satisfy quite easily points 2 and 3, but we need to provide some wrapper facility to make them compatible to 1, 4 and 5. In fact the XML Schema specification requires having the ID unique at the document level (the domain is the document).
Integers, which are widely used in databases, satisfy only point 3.
Strings are widely used in account databases, to identify people (i.e. their SSN), or companies, etc. In fact the string can satisfy all points except 5.
Personally, I really like to idea of composite ID, where the compounds are the domain and the domain based ID. In C# we can use generics to manage IDs as I did in the following (untested) class:
public class Id<TId> : IEquatable<Id<TId>>
{
public Id(string domain, TId id)
: this(domain, id, "/")
{
}
public Id(string domain, TId id, string separator)
{
if (string.IsNullOrEmpty(domain))
throw new ArgumentNullException("domain");
if (id == null)
throw new ArgumentNullException("id");
if (string.IsNullOrEmpty(separator))
throw new ArgumentNullException("separator");
this.domain = domain;
this.id = id;
this.separator = separator;
}
public string Domain
{
get { return domain; }
}
public TId DomainId
{
get { return id; }
}
public string FullId
{
get { return this.ToString(); }
}
public override int GetHashCode()
{
return domain.GetHashCode() ^ id.GetHashCode();
}
public override bool Equals(object obj)
{
if (!(obj is Id<TId>))
throw new ArgumentException("obj");
return Equals((Id<TId>)obj);
}
public bool Equals(Id<TId> other)
{
return other.domain.Equals(this.domain, StringComparison.OrdinalIgnoreCase) &&
other.id.Equals(this.id);
}
public override string ToString()
{
return string.Concat(domain, separator, id);
}
public static bool operator ==(Id<TId> x, Id<TId> y)
{
return x.Equals(y);
}
public static bool operator !=(Id<TId> x, Id<TId> y)
{
return !x.Equals(y);
}
private string domain;
private TId id;
private string separator;
}
In this way we can quite easly manage simple Ids (GUID, int, string) as well as composed Ids (all you need to do is to override ToString, Equals and GetHashCode).
Many times we design our special kind of bit field to manage bitwise operations on enums. Here a simple example:
[
Flags]
public enum ConsoleModiefiers
{
Alt = 2,
Control = 4,
Shift = 8
}
When the number of values becomes higher, we have a little readibility problem with the value for each field. A possible alternative is to use the left-shift operator
[Flags]
public enum ConsoleModiefiers
{
Alt = 0x0001 << 1,
Control = 0x0001 << 2,
Shift = 0x0001 << 3
}
In term of performance we don't pay any penalties since the IL code generated by C# compiler is exactly the same, but our code is probably more clear.
The User Account Control is not only about technology or security, but also about good breeding. As developers we would like not to have face with security problems, works every time as adminsitrators and work without any security checking. As end users we would have a secure system wihout having to say yes or no for anything we do with our PC.
But the world is unsecure by design and everytime we connect to Internet we are potentially subject to some kind of attack. What is our gate to Internet, most of the time is Internet Explorer. Under Vista the UAC has a big influence in IE7 as explained by Sharath. Maybe the current usability of the UAC is not perfect but disabling it is even worse. And if you really want to be safe at 100%, unplug the network cable and remove any CD/DVD/Diskette driver from your pc :-)
It seems a good day for starting the blog :-) I don't have plan for any particular topic with this blog, but you'll quickly discover several thinks of me:
- I continue to practice my English
- I really like Service Oriented Architectures
- I think developer tools really need to help developers
Let’s see, who I am. I’m software developer at MSTV in server team. IPTV Edition is a very interesting product where just few people can work with it, but milions of people use it :-) It's simply fun.
Disclaimer
The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.
So, see you soon ...