DNS – Excessive Memory Usage by DNSCache in Windows Server 2008 R2

domain-name-systemmemorymemory leakwindows-server-2008-r2

We are having an issue with the dnscache service where its memory usage is becoming excessive (~6GB) after a week or two.

Restarting the service frees this memory but performing ipconfig /flushdns does not, an ipconfig /displaydns shows aprox 15-20 entries in the cache.

We have checked and there appears to be aprox 150 DNS queries per second taking place but I would not expect this to have the effect of causing this memory issue.

I have tried to search MSDN for hotfixes or bug reports but I could only find a reference to a memory leak in windows 2003. can anyone suggest how to proceed.

Best Answer

Given that you’ve already searched for hotfixes, I assume you server is already up to date with the latest Windows Service Pack and current on all updates? That’s always the best place to start.

With a cache size of 6 GB, we’re talking tens of millions of unique DNS results (which is absurd). It’s unlikely that your clients would be making that many unique DNS queries. In the comments of your question, you indicated that the application is performing lookups each time a client sends data to the server. I don’t know how the application (I’m assuming web application) on your server works, but I wonder if some event is creating unique DNS queries with each client request, queries that get returned as a non-existent domains. I suppose that if the DNS query hits a domain with a wildcard, they might be returning valid responses. Either way, this could account for the huge cache size.

Ipconfig /displaydns does not always return the entire cache, which would explain why you’re only seeing 15-20 entries.

You can (at least I can) confirm this by performing the following…

From a Powershell prompt:

> ipconfig /flushdns
> [System.Net.Dns]::GetHostAddresses(“google.com”)

Check out the DNS cache

> ipconfig /displaydns

You’ll probably see the Google.com entry. Make note of the cache size using the task manager (in Task Manager, find the dnscache service, right click on it, select go to process).

Now run the following command, where ### is a large number (I used 10,000). Note, I set up my local DNS server to respond to all .test subdomains with a wildcard so I didn’t hit my ISPs DNS server 10,000 times in a short period of time.

> $i = 0
> do {[System.Net.Dns]::GetHostAddresses(“blahblahfakedomain” + $i++ + “.test”)} while ($i –lt ###)

As the command executes, watch the cache process’s memory utilization grow in Task Manager. Once it completes, check out the cache. You probably won’t see the ### quires we just generated, but the DNS Cache processes hasn’t released the memory.

In my experiments, I was able to recover the memory by flushing the DNS cache (10,000 queries is about 2 megs). I don’t know why that doesn’t work for you. Maybe because the cache is so darn big…?

Anyway, I propose the following workaround:

Modify the MaxCacheTtl and MaxNegativeCacheTtl registry values under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters key per (http://support.microsoft.com/kb/318803):

Modify or create the DWord value MaxCacheTtl, setting it to something low, like 3600 seconds (0xE10 in hex). All values are specified in seconds. The default is 1 day (86,400 seconds).

Modify or create the DWord value MaxNegativeCacheTtl, setting it to 0.

This will cause all records to be cleared from the cache at most an hour after they are added. Negative results (non-existent domains) won’t be stored in the cache at all (I’ve confirmed this on my Windows 7 desktop).

I call this a workaround because I would say the problem lies with whatever process is creating the absurd amount of requests. If you can, try to quench the torrent of requests from the source.