SQL Server cannot obtain a LOCK resource at this time I'm somewhat familiar with blocking processes and locks in SQL Server, however this one has me pretty confused. I understand this error can come from two issues: 1) if SQL Server cannot allocate more memory for locks or 2) if there is a blocking process.

I do not believe #1 is the issue as the machine has 48GB memory and only ~14GB is used. SQL Server is configured to use a max of 2,147,483,647MB of memory.

With #2, when I run sp_lock, I see a row with an ObjID and a TABLE lock, mode IS. This lock is under the same process I am running SSMS under. Therefore when I try to do a KILL on the process, I get the error "Cannot use KILL to kill your own process."

I have restarted the server a couple of times and closed SSMS and still this lock persists. My program can't do work on the relevant table because of the lock; it keeps getting the error message that SQL Server cannot obtain a lock and to try again at a less-busy time. There is no activity on the server, I am the sole user. Therefore I do not believe this is a resource issue, but firmly related to the lock I can't seem to get rid of.

I have run a modified sp_lock procedure that uses sp_who in conjunction to try and determine who is blocking who. In this view, I see my userid has one IS mode lock, but it is not an exclusive lock.

How can I release the table lock? What is happening with the database? How can I avoid this issue in the future?
the machine has 48GB memory and only ~14GB is used. SQL Server is configured to use a max of 2,147,483,647MB of memory.

This does not tell wether the locks memory is exhausted or not. SQL Server will use for the lock manager either the configured sp_configure 'locks' value or, by default, some percent of the available total memory. The lock manager can well exhaust the available locks memory w/o the total memory exceeding the 14GB you see. you need to check SQL Server, Memory Manager Object:

Lock Blocks   Specifies the current number of lock blocks in use on the server (refreshed periodically). A lock block represents an individual locked resource, such as a table, page, or row.
Lock Blocks Allocated Specifies the current number of allocated lock blocks. At server startup, the number of allocated lock blocks plus the number of allocated lock owner blocks depends on the SQL Server Locks configuration option. If more lock blocks are needed, the value increases.
Lock Memory (KB)  Specifies the total amount of dynamic memory the server is using for locks.
Lock Owner Blocks Specifies the number of lock owner blocks currently in use on the server (refreshed periodically). A lock owner block represents the ownership of a lock on an object by an individual thread. Therefore, if three threads each have a shared (S) lock on a page, there will be three lock owner blocks.
Lock Owner Blocks Allocated   Specifies the current number of allocated lock owner blocks. At server startup, the number of allocated lock owner blocks and the number of allocated lock blocks depend on the SQL Server Locks configuration option. If more lock owner blocks are needed, the value increases dynamically.

However, in your case, I do not believe the problem to be lock manager memory exhaustion. It could be a lock held by an orphaned transaction, although is very unclear from your explanation. To begin with, post the exact error message your application is seeing. Normally applications either get the lock, or they wait. An infinity. A 'could not get the lock' message would imply some very specific context (eg. attempt to obtain a lock for ALTER DB). So is very important to know what message you get, and the exact statement being executed when you get the message.
Next step, depending on the result of the previous steps, is to look into sys.dm_tran_locks.