PHP'nin APC belleği geri gelmez apc_delete sonra () denir?

2 Cevap php

APC çalıştığını yolu belgelenmiştir nerede daha genel, herkes biliyor?

2 Cevap

Kısa cevap evet, bellek boşaltmak ve geri kazanmak için görünür olduğunu. Ben gitmek gibi çağrı yığını içine daha fazla dahil inen ana fonksiyonları, listeledik:

  1. apc_delete
  2. apc_cache_user_delete
  3. remove_slot
  4. free_slot
  5. apc_sma_free
  6. sma_deallocate

apc_delete

// taken from the file php_apc.c
// http://php-apc.sourcearchive.com/documentation/3.0.18/php__apc_8c-source.html

/* {{{ proto mixed apc_delete(string key)
 */
PHP_FUNCTION(apc_delete) {
    char *strkey;
    int strkey_len;

    if(!APCG(enabled)) RETURN_FALSE;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &strkey, &strkey_len) == FAILURE) {
        return;
    }

    if(!strkey_len) RETURN_FALSE;

    if(apc_cache_user_delete(apc_user_cache, strkey, strkey_len + 1)) {
        RETURN_TRUE;
    } else {
        RETURN_FALSE;
    }
}
/* }}} */

apc_cache_user_delete

// taken from the file apc_cache.c
// http://php-apc.sourcearchive.com/documentation/3.0.18/apc__cache_8c-source.html

/* {{{ apc_cache_user_delete */
int apc_cache_user_delete(apc_cache_t* cache, char *strkey, int keylen)
{
    slot_t** slot;

    LOCK(cache);

    slot = &cache->slots[string_nhash_8(strkey, keylen) % cache->num_slots];

    while (*slot) {
        if (!memcmp((*slot)->key.data.user.identifier, strkey, keylen)) {
            remove_slot(cache, slot);
            UNLOCK(cache);
            return 1;
        }
        slot = &(*slot)->next;
    }

    UNLOCK(cache);
    return 0;
}
/* }}} */

remove_slot

// taken from the file apc_cache.c
// http://php-apc.sourcearchive.com/documentation/3.0.18/apc__cache_8c-source.html

/* {{{ remove_slot */
static void remove_slot(apc_cache_t* cache, slot_t** slot)
{
    slot_t* dead = *slot;
    *slot = (*slot)->next;

    cache->header->mem_size -= dead->value->mem_size;
    cache->header->num_entries--;
    if (dead->value->ref_count <= 0) {
        free_slot(dead);
    }
    else {
        dead->next = cache->header->deleted_list;
        dead->deletion_time = time(0);
        cache->header->deleted_list = dead;
    }
}
/* }}} */

free_slot

// taken from the file apc_cache.c
// http://php-apc.sourcearchive.com/documentation/3.0.18/apc__cache_8c-source.html

/* {{{ free_slot */
static void free_slot(slot_t* slot)
{
    if(slot->value->type == APC_CACHE_ENTRY_USER) {
        apc_sma_free((char *)slot->key.data.user.identifier);
    } else if(slot->key.type == APC_CACHE_KEY_FPFILE) {
        apc_sma_free((char *)slot->key.data.fpfile.fullpath);
    }
    apc_cache_free_entry(slot->value);
    apc_sma_free(slot);
}
/* }}} */

apc_sma_free

// taken from the file apc_sma.c
// http://php-apc.sourcearchive.com/documentation/3.0.18/apc__sma_8c-source.html

/* {{{ apc_sma_free */
void apc_sma_free(void* p)
{
    int i;
    size_t offset;
    size_t d_size;
    TSRMLS_FETCH();

    if (p == NULL) {
        return;
    }

    assert(sma_initialized);

    for (i = 0; i < sma_numseg; i++) {
        LOCK(((header_t*)sma_shmaddrs[i])->sma_lock);
        offset = (size_t)((char *)p - (char *)(sma_shmaddrs[i]));
        if (p >= sma_shmaddrs[i] && offset < sma_segsize) {
            d_size = sma_deallocate(sma_shmaddrs[i], offset);
            if (APCG(mem_size_ptr) != NULL) { *(APCG(mem_size_ptr)) -= d_size; }
            UNLOCK(((header_t*)sma_shmaddrs[i])->sma_lock);
#ifdef VALGRIND_FREELIKE_BLOCK
            VALGRIND_FREELIKE_BLOCK(p, 0);
#endif
            return;
        }
        UNLOCK(((header_t*)sma_shmaddrs[i])->sma_lock);
    }

    apc_eprint("apc_sma_free: could not locate address %p", p);
}
/* }}} */

sma_deallocate

// taken from the file apc_sma.c
// http://php-apc.sourcearchive.com/documentation/3.0.18/apc__sma_8c-source.html

/* {{{ sma_deallocate: deallocates the block at the given offset */
static size_t sma_deallocate(void* shmaddr, size_t offset)
{
    header_t* header;   /* header of shared memory segment */
    block_t* cur;       /* the new block to insert */
    block_t* prv;       /* the block before cur */
    block_t* nxt;       /* the block after cur */
    size_t size;        /* size of deallocated block */

    offset -= ALIGNWORD(sizeof(struct block_t));
    assert(offset >= 0);

    /* find position of new block in free list */
    cur = BLOCKAT(offset);
    prv = BLOCKAT(ALIGNWORD(sizeof(header_t)));

    CHECK_CANARY(cur);

#ifdef __APC_SMA_DEBUG__
    CHECK_CANARY(prv);
    fprintf(stderr, "free(%p, size=%d,id=%d)\n", cur, (int)(cur->size), cur->id);
#endif
    while (prv->next != 0 && prv->next < offset) {
        prv = BLOCKAT(prv->next);
#ifdef __APC_SMA_DEBUG__
        CHECK_CANARY(prv);
#endif
    }

    CHECK_CANARY(prv);

    /* insert new block after prv */
    cur->next = prv->next;
    prv->next = offset;

#ifdef __APC_SMA_DEBUG__
    CHECK_CANARY(cur);
    cur->id = -1;
#endif

    /* update the block header */
    header = (header_t*) shmaddr;
    header->avail += cur->size;
    size = cur->size;

    if (((char *)prv) + prv->size == (char *) cur) {
        /* cur and prv share an edge, combine them */
        prv->size += cur->size;
        prv->next = cur->next;
        RESET_CANARY(cur);
        cur = prv;
    }

    nxt = BLOCKAT(cur->next);

    if (((char *)cur) + cur->size == (char *) nxt) {
        /* cur and nxt shared an edge, combine them */
        cur->size += nxt->size;
        cur->next = nxt->next;
#ifdef __APC_SMA_DEBUG__
        CHECK_CANARY(nxt);
        nxt->id = -1; /* assert this or set it ? */
#endif
        RESET_CANARY(nxt);
    }
    header->nfoffset = 0;  /* Reset the next fit search marker */

    return size;
}
/* }}} */

The core files can be found here: http://php-apc.sourcearchive.com/documentation/3.0.18/files.html

Evet, ama: saklamak çok yapmak ve silerseniz bellek parçalanmış alır. Ve apc Yani bellek serbest ama kullanılamaz "birleştirmek" bellek ve bir süre sonra yeni var uyuyor yeterli boş alan bulmak olmayabilir için bir yol yoktur.

Eğer bu gerçekleşirse, apc genellikle siler everything. (O) yapılandırılabilir