MuhanadY
MuhanadY

Reputation: 730

Redis throw exception "System.OutOfMemoryException"

I have an object which holds 15 properties. the object stored in a List of its own type but the list is a bit big (330.000 object). I do set the object to be stored in Redis and all fine. the problem that i have is when Getting the list from Redis, i receive System.OutOfMemoryException (keep on mind that enough memory and disk space i have). below is the stacktrace of the exception

  at System.String.CreateStringFromEncoding(Byte* bytes, Int32 byteLength, Encoding encoding)
   at System.Text.UTF8Encoding.GetString(Byte[] bytes, Int32 index, Int32 count)
   at ServiceStack.StringExtensions.FromUtf8Bytes(Byte[] bytes)
   at ServiceStack.Redis.RedisClient.GetValue(String key)
   at ServiceStack.Redis.RedisClient.<>c__DisplayClass1c`1.<Get>b__1b(RedisClient r)
   at ServiceStack.Redis.RedisClient.Exec[T](Func`2 action)
   at ServiceStack.Redis.RedisClient.Get[T](String key)
   at KaysisClientCache.RedisCacheProvider.GetCache[T](CacheNames key, Func`2 query) in d:\BBProjects\BBSunucu\KaysisClientCache\RedisCacheProvider.cs:line 32

and below is the way that i set the cache

redisClient.Set(cacheOb.Name, cacheItem, DateTime.Now.AddMinutes(cacheOb.TimeoutInMin));

and here is the way that get the cache

return query != null ? redisClient.Get<List<T>>(key.ToString()).Where(query).ToList() : redisClient.Get<List<T>>(key.ToString()).ToList();

any help is appreciated by the way Am using ServiceStack.Redis ver. 4.0.35.0

Upvotes: 1

Views: 2815

Answers (1)

efaruk
efaruk

Reputation: 953

First, you could be using StackExchange.Redis, Service Stack has some limitations (Free version). Second, you could use Binary as following:

    public static byte[] Serialize(object value)
    {
        if (value == null) return null;
        if (!value.GetType().IsSerializable) return null;
        byte[] result;
        using (var stream = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(stream, value);
            result = stream.ToArray();
        }
        return result;
    }

    public static object Deserialize(byte[] value)
    {
        if (value == null) return null;
        object result;
        using (var stream = new MemoryStream(value))
        {
            var formatter = new BinaryFormatter();
            result = formatter.Deserialize(stream);
        }
        return result;
    }

And you could use StringSet and StringGet methods from StackExchange.Redis client, no matter what you are storing on redis, if you are not gonna do some operation on redis with that data (pleas check: sorted set, redis data types). You can use as following;

...
var data = redisDatabase.StringGet(key);
var result = Deserialize(data);
...
var data = (RedisValue)Serialize(value);
var result = redisDatabase.StringSet(key, data, expireTime);
...

Important Note: Please verify you have 64 bit environment, If you are developing in asp.net please verify you are using IIS Express x64 (How to force VS to run iis express 64 bit). Please check from "Task Manager" for Windows 7 32 bit applications appears with a star, for Windows 8 32 bit applications appears as (32 bit).

I Hope it would work for you, regards...

Upvotes: 1

Related Questions