jakarta-jcs-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "David Luk" <David....@tvnz.co.nz>
Subject LRUMemoryCache Error
Date Fri, 14 May 2004 04:48:56 GMT

Hi everyone,

This is my first post to this mailing-list and hopefully I asked this
question in the right place.

I have some problems when running my remote JCS server. I am running
remote JCS with multiple cocoon 2.1.4 instances.

There is an error "java.lang.Error: update: last is null" occurred at
random time triggered by the LRUMemoryCache class.
I have narrowed down the problem and suspected the problem is due to the
synchronized block in the update method may not be broad enough.

Has anyone got the similar problem and would you suggest putting the
synchronized keyword to the method declaration?
Would that be any performance impact if I do this?

Appreciate your help.

Many thanks,
David Luk

    /**
     *  Puts an item to the cache.
     *
     *@param  ce               Description of the Parameter
     *@exception  IOException
     */
    public void update( ICacheElement ce )
        throws IOException
    {
        // Asynchronisly create a MemoryElement

        ce.getElementAttributes().setLastAccessTimeNow();
        addFirst( ce );
        MemoryElementDescriptor old =
            ( MemoryElementDescriptor ) map.put( first.ce.getKey(),
first );

        // If the node was the same as an existing node, remove it.

        if ( old != null && first.ce.getKey().equals( old.ce.getKey() )
)
        {
            removeNode( old );
        }

        int size = map.size();
        // If the element limit is reached, we need to spool

        if ( size < this.cattr.getMaxObjects() )
        {
            return;
        }
        else
        {
            log.debug( "In memory limit reached, spooling" );

            // Write the last 'chunkSize' items to disk.

            int chunkSizeCorrected = Math.min( size, chunkSize );

            if ( log.isDebugEnabled() )
            {
                log.debug( "About to spool to disk cache, map size: " +
size
                     + ", max objects: " + this.cattr.getMaxObjects()
                     + ", items to spool: " + chunkSizeCorrected );
            }

            // The spool will put them in a disk event queue, so there
is no
            // need to pre-queue the queuing.  This would be a bit
wasteful
            // and wouldn't save much time in this synchronous call.

            for ( int i = 0; i < chunkSizeCorrected; i++ )
            {
               synchronized ( this )
               {
                    if ( last != null )
                    {
                        if ( last.ce != null )
                        {
                            cache.spoolToDisk( last.ce );
                            if ( !map.containsKey(last.ce.getKey()) )
                            {
                                log.error("update: map does not contain
key: " + last.ce.getKey());
                                verifyCache();
                            }
                            if ( map.remove(last.ce.getKey()) == null )
                            {
                                log.warn("update: remove failed for key:
" + last.ce.getKey() );
                                verifyCache();
                            }
                        }
                        else
                        {
                            throw new Error("update: last.ce is null!");
                        }
                        removeNode( last );
                    }
                    else
                    {
                        verifyCache();
                        throw new Error("update: last is null!");
                    }
               }
            }

            if ( log.isDebugEnabled() )
            {
                log.debug("update: After spool map size: " +
map.size());
            }
            if ( map.size() != dumpCacheSize() )
            {
                log.error("update: After spool, size mismatch:
map.size() = "
                          + map.size() + ", linked list size = " +
                          dumpCacheSize());
            }
        }
    }


================================================================
CAUTION: This e-mail and any attachment(s) contains information
that is intended to be read only by the named recipient(s). It
may contain information that is confidential, proprietary or the
subject of legal privilege. This information is not to be used by
any other person and/or organisation. If you are not the intended
recipient, please advise us immediately and delete this e-mail
from your system. Do not use any information contained in it.

================================================================
For more information on the Television New Zealand Group, visit
us online at http://www.tvnz.co.nz
================================================================
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message