Hi Sergei,

For various reasons (performance, avoiding memory fragmentation), memcached uses a memory allocation approach called slab allocation. The memcached flavor of it can be found here:

http://code.google.com/p/memcached/wiki/MemcachedSlabAllocator

Chances are, your items didn't fit into the slabs defined. There are some stats to see the details and you can potentially do some slab tuning.

Hope that helps,

- Matt

siroga wrote:
Hi,
I just started playing with memcached. While doing very basic stuff I
found one thing that confused me a lot.
I have memcached running with default settings - 64M of memory for
caching.
1. Called flushALL to clean the cache.
2. insert 100 of byte arrays 512K each - this should consume about 51M
of memory so  I should have enough space to keep all of them - and to
very that call get() for each of them  - as expected all arrays are
present
3. I call flushAll again - so cache should be clear
4. insert 100 arrays of smaller size ( 256K). I also expected that I
have enough memory to store them (overall I need about 26M), but
surprisingly to me when calling get() only last 15 where found in the
cache!!!

It looks like memcached still hold memory occupied by first 100
arrays.
Memcache-top says that only 3.8M out of 64 used.

Any info/explanation on memcached memory management details is very
welcomed. Sorry if it is a well known feature, but I did not find much
on a wiki that would suggest explanation.

Regards,
Sergei

Here is my test program (I got the same result using both danga and
spy.memcached. clients):

    MemCachedClient cl;

@Test
    public void strange() throws Throwable
    {
        byte[] testLarge = new byte[1024*512];
        byte[] testSmall = new byte[1024*256];
        int COUNT = 100;
        cl.flushAll();
        Thread.sleep(1000);
        for (int i = 0; i < COUNT; i++)
        {
            cl.set("largekey" + i, testLarge, 600);
        }
        for (int i = 0; i < COUNT; i++)
        {
            if (null != cl.get("largekey" + i))
            {
                System.out.println("First not null " + i);
                break;
            }
        }
        Thread.sleep(1000);
        cl.flushAll();
        Thread.sleep(1000);
        for (int i = 0; i < COUNT; i++)
        {
            cl.set("smallkey" + i, testSmall, 600);
        }
        for (int i = 0; i < COUNT; i++)
        {
            if (null != cl.get("smallkey" + i))
            {
                System.out.println("First not null " + i);
                break;
            }
        }

    }

Reply via email to