BigMemroy系列文章--12. Ehcache和BigMemory常见问题

阅读更多

转载请注明出处哈:http://carlosfu.iteye.com/blog/2237511


 

问题目录:

  • 一、Ehcache、BigMemory Go和BigMemory Max的关系
  • 二、copyOnRead配置分析
  • 三、BigMemory的sizeOf问题:
  • 四、timeToLive和timeToIdle配置分析
  • 五、Ehcache的统计配置和说明:
  • 六、Ehcache的常用的eviction算法:
  • 七、MaxEntries和MaxBytes配置选择问题:
  • 八、哪些配置参数可以运行时动态修改
  • 九、Ehcache批量操作优化:
  • 十、是否要使用磁盘
  • 十一、Element生命周期
  • 十二、序列化问题

 

 

一、Ehcache、BigMemory Go和BigMemory Max的关系

(1) terracotta收购了Ehcache,在Ehcache基础上开发了商业版的BigMemory Go(单机版:有试用期)和BigMemory Max(集群版:收费)。

(2) BigMemory支持使用堆外内存,有效利用本机内存并有效防止GC。

(3) Ehcache和BigMemory的API几乎完全一致。

二、 copyOnRead配置分析:

1. Ehcache进行cache.get()操作时,内存模型示意图


BigMemroy系列文章--12. Ehcache和BigMemory常见问题_第1张图片
 

2. copyOnRead配置的几点说明:

(1) copyOnRead=false是默认值

(2) copyOnRead=false的话,当调用cache.get(key)时,引用的(o1-o4)都是同一个对象,

    也就是说,如果有其他线程对该Element其进行update时,o1-o4也会使用新的value。

(3) copyOnRead=true的话,可以看右边的示意图,很明显(o1-o4)引用是copy的新对象(每个一份新的copy)。

     也就是说,如果有其他线程对该Element其进行update时,o1-o4仍然会使用老value。

(4) 优缺点:

copyOnRead=false 节省空间 线程不安全
copyOnRead=true 线程安全 浪费空间

 

3. copyOnRead测试实验:

(0) cache.put()一个element, 然后循环get,观察在copyOnRead=false|true时,cache.get(key)打印值

 

package com.sohu.tv.ehcache.config;
import net.sf.ehcache.Element;
import org.junit.Test;
import com.sohu.tv.ehcache.base.BaseTest;
/**
 * ehcache中copyOnRead测试
 * 
 * @author leifu
 * @Date 2015-8-16
 * @Time 下午9:02:56
 */
public class EhcacheCopyOnReadTest extends BaseTest {
    @Test
    public void testCopyOnRead() throws InterruptedException {
        //写
        String key = "bigKey";
        byte[] bytes = new byte[1024 * 1024];
        Element element = new Element(key, bytes);
        cache.put(element);
        //循环get
        for (int i = 0; i < 10; i++) {
            logger.info(cache.get(key).toString());
        }
    }
}
 

   (1) 当copyOnRead=false:为同一个value

 

21:51:48.844 [main] INFO com.sohu.tv.ehcache.base.BaseTest - cacheName: firstEhcache
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=1, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=2, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=3, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=4, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=5, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=6, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=7, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=8, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=9, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
21:51:48.853 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@93271bd, version=1, hitCount=10, CreationTime = 1439733108850, LastAccessTime = 1439733108853 ]
   (2) 当copyOnRead=true,为不同value

 

21:50:48.067 [main] INFO com.sohu.tv.ehcache.base.BaseTest - cacheName: firstEhcache
21:50:48.083 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@68e5ccce, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048083 ]
21:50:48.086 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@46e91e2f, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048086 ]
21:50:48.092 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@72bcc407, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048092 ]
21:50:48.097 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@46e9e26a, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048097 ]
21:50:48.102 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@250fc185, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048101 ]
21:50:48.106 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@2d6a15c5, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048106 ]
21:50:48.120 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@1013106d, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048120 ]
21:50:48.123 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@539b6c59, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048123 ]
21:50:48.126 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@e671f1, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048125 ]
21:50:48.130 [main] INFO c.s.t.e.config.EhcacheCopyOnReadTest - [ key = bigKey, value=[B@194285ad, version=1, hitCount=1, CreationTime = 1439733048073, LastAccessTime = 1439733048130 ]
 

   (3)对(2)进一步测试

    设置jvm运行参数:-Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError

package com.sohu.tv.ehcache.config;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import net.sf.ehcache.Element;
import org.junit.Test;
import com.sohu.tv.ehcache.base.BaseTest;
/**
 * ehcache中copyOnRead测试 
 * vm:-Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError
 * 
 * @author leifu
 * @Date 2015-8-16
 * @Time 下午9:02:56
 */
public class EhcacheCopyOnReadTest extends BaseTest {
    @Test
    public void testCopyOnReadHeap() throws InterruptedException {
        String key = "bigKey";
        byte[] bytes = new byte[1024 * 1024];
        Element element = new Element(key, bytes);
        cache.put(element);
        List list = new ArrayList();
        for (int i = 0; i < 10; i++) {
            Element e = cache.get(key);
            byte[] aa = (byte[]) e.getObjectValue();
            list.add(aa);
        }
    }
}

 

  运行会报错,发生了Java heap space,进一步证明了copyOnRead=true时获取的是复制品。

java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2271)
at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:113)
at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:140)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1876)
at java.io.ObjectOutputStream$BlockDataOutputStream.flush(ObjectOutputStream.java:1821)
at java.io.ObjectOutputStream.flush(ObjectOutputStream.java:718)
at java.io.ObjectOutputStream.close(ObjectOutputStream.java:739)
at net.sf.ehcache.store.compound.ReadWriteSerializationCopyStrategy.copyForWrite(ReadWriteSerializationCopyStrategy.java:58)
at net.sf.ehcache.store.compound.ReadWriteSerializationCopyStrategy.copyForWrite(ReadWriteSerializationCopyStrategy.java:34)
at net.sf.ehcache.store.FrontEndCacheTier.copyElementForReadIfNeeded(FrontEndCacheTier.java:145)
at net.sf.ehcache.store.MemoryOnlyStore.get(MemoryOnlyStore.java:107)
at net.sf.ehcache.Cache.searchInStoreWithStats(Cache.java:1955)
at net.sf.ehcache.Cache.get(Cache.java:1584)
at net.sf.ehcache.Cache.get(Cache.java:1557)
at com.sohu.tv.ehcache.config.EhcacheCopyOnReadTest.testCopyOnReadHeap(EhcacheCopyOnReadTest.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
 

  4. copyOnRead生产环境的选择:

   选择依据业务的需要,根据第二节中copyOnRead的配置说明,来进行选择。

 

三、BigMemory的sizeOf问题:(具体参考BigMemroy系列文章--11. BigMemory中的SizeOf问题)

几点总结:

(1) Bigmemory的主要开销:序列化+sizeOf计算

(2)对sizeOf引擎友好的对象:尽量使用不深/不广的对象:深(继承树) 广( bigPojo,ArrayList,HashMap等)

(3)采用预前序列化的方式,bigMemory只存序列化后的byte数组, 就不会出现sizeof问题

 

四、timeToLive和timeToIdle配置分析:

1. 先看下官方文档的解释:

 

Expiration settings
timeToLive – The maximum number of seconds an element can exist in the cache regardless of access.
The element expires at this limit and will no longer be returned from the cache. The default value is 0, which means no TTL eviction takes place (infinite lifetime).
timeToIdle – The maximum number of seconds an element can exist in the cache without being accessed.
The element expires at this limit and will no longer be returned from the cache. The default value is 0, which means no TTI eviction takes place (infinite lifetime).

 

2. timeToLive和timeToIdle理解

英语不太好,上面除了红色的不一样,解释是一样的,一开始没理解这个配置的意思,通过测试终于明白了。

timeToLive(TTL): 可以理解成过期时间,不管key是否在过期时间内被访问了,到了过期时间就从cache中移除(get()不到了,实际通过测试发现没有立即删除,应该是ehcache有一些过期删除策略)

timeToIdle(TTI): 可以理解成最大闲置时间,如果key在此期间被访问,那么TTI将恢复原值。

两者比较:TTL是到点一定过期,TTI是到点不一定过期(期间被访问了)

 

3. timeToLive和timeToIdle测试实验

(1) timeToLive:
 (a) 配置新加timeToLiveSeconds="10"


    
    

  

(b)测试代码
package com.sohu.tv.ehcache.ttl;
import java.util.concurrent.TimeUnit;
import net.sf.ehcache.Element;
import org.junit.Test;
import com.sohu.tv.ehcache.base.BaseTest;
/**
 * 测试timeToLive配置
 * @author leifu
 * @Date 2015-8-17
 * @Time 下午8:12:10
 */
public class EhcacheTimeToLiveTest extends BaseTest {
    @Test
    public void testTimeToLive() throws InterruptedException {
        // put一个Element,ehcache.xml设置 timeToLiveSeconds="10"
        String key = "ttlKey";
        byte[] bytes = new byte[1024];
        Element element = new Element(key, bytes);
        cache.put(element);
        logger.info("after put, ehcache object size: " + cache.getSize());
        // 等待10秒过期
        for (int i = 10; i > 0; i--) {
            Element e = cache.get(key);
            long remainSecondsToExpire = 0;
            try {
                remainSecondsToExpire = (e.getExpirationTime() - System.currentTimeMillis()) / 1000;
            } catch (Exception exception) {
            }
            logger.info("key {} remain {} seconds to expire", key, remainSecondsToExpire);
            TimeUnit.SECONDS.sleep(1);
        }
        // 过期后再次获取
        Element e = cache.get(key);
        logger.info("exceed ttl get element is {}", e);
        logger.info("At final, ehcache object size: " + cache.getSize());
    }
}

 

(c) 输出:
14:12:40.057 [main] INFO com.sohu.tv.ehcache.base.BaseTest - cacheName: firstEhcache
14:12:40.066 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - after put, ehcache object size: 1
14:12:40.067 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 9 seconds to expire
14:12:41.067 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 8 seconds to expire
14:12:42.068 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 7 seconds to expire
14:12:43.070 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 6 seconds to expire
14:12:44.070 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 5 seconds to expire
14:12:45.070 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 4 seconds to expire
14:12:46.070 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 3 seconds to expire
14:12:47.071 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 2 seconds to expire
14:12:48.071 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 1 seconds to expire
14:12:49.071 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - key ttlKey remain 0 seconds to expire
14:12:50.072 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - exceed ttl get element is null
14:12:50.072 [main] INFO c.s.t.e.ttl.EhcacheTimeToLiveTest - At final, ehcache object size: 0

  

(2) timeToIdle:
(a) 新加配置timeToIdleSeconds="10"

 



    
    
 

 

 (b) 测试代码

 

package com.sohu.tv.ehcache.ttl;
import java.util.concurrent.TimeUnit;
import net.sf.ehcache.Element;
import org.junit.Test;
import com.sohu.tv.ehcache.base.BaseTest;
/**
 * ehcache TimeToIdle测试
 * 
 * @author leifu
 * @Date 2015-8-17
 * @Time 下午8:12:10
 */
public class EhcacheTimeToIdleTest extends BaseTest {
    @Test
    public void testTimeToIdle() throws InterruptedException {
        // put一个Element,ehcache.xml设置 timeToIdleSeconds="10"
        String key = "ttiKey";
        byte[] bytes = new byte[1024];
        Element element = new Element(key, bytes);
        cache.put(element);
        logger.info("after put, ehcache object size: " + cache.getSize());
        Element e = null;
        // 等待10秒过期
        for (int i = 10; i > 0; i--) {
            logger.info("sleep {} seconds wait expire", i);
            if (i == 2) {
                logger.info("ehcache get key {}", key);
                e = cache.get(key);
            }
            TimeUnit.SECONDS.sleep(1);
        }
        logger.info("element is {}", e);
        long remainSecondsToExpire = (e.getExpirationTime() - System.currentTimeMillis()) / 1000;
        // 推测还有8秒(10-2)过期
        logger.info("key {} remain {} seconds to expire", key, remainSecondsToExpire);
        // 再次get,重置过期时间
        e = cache.get(key);
        remainSecondsToExpire = (e.getExpirationTime() - System.currentTimeMillis()) / 1000;
        // 推测重置成10秒过期
        logger.info("key {} remain {} seconds to expire", key, remainSecondsToExpire);
        logger.info("At final, ehcache object size: " + cache.getSize());
    }
}
 
 (c) 输出:

14:14:54.749 [main] INFO com.sohu.tv.ehcache.base.BaseTest - cacheName: firstEhcache
14:14:54.760 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - after put, ehcache object size: 1
14:14:54.760 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 10 seconds wait expire
14:14:55.760 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 9 seconds wait expire
14:14:56.761 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 8 seconds wait expire
14:14:57.761 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 7 seconds wait expire
14:14:58.761 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 6 seconds wait expire
14:14:59.761 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 5 seconds wait expire
14:15:00.761 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 4 seconds wait expire
14:15:01.761 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 3 seconds wait expire
14:15:02.763 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 2 seconds wait expire
14:15:02.763 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - ehcache get key ttiKey
14:15:03.764 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - sleep 1 seconds wait expire
14:15:04.764 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - element is [ key = ttiKey, value=[B@145650eb, version=1, hitCount=1, CreationTime = 1439878494756, LastAccessTime = 1439878502764 ]
14:15:04.764 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - key ttiKey remain 8 seconds to expire
14:15:04.764 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - key ttiKey remain 10 seconds to expire
14:15:04.765 [main] INFO c.s.t.e.ttl.EhcacheTimeToIdleTest - At final, ehcache object size: 1

 

4. timeToLive和timeToIdle优先级高

 

请参考:http://blog.csdn.net/vtopqx/article/details/8522333

 

5. 生产环境中的使用情况:

(1) 如果配置了eternal=true那么timeToLive和timeToIdle就会无效

(2) 一般来说,timeToLive和timeToIdle不会配置,eternal也是false,

      每个Element的过期是通过java代码实现的,这样控制过期时间更加灵活。

public Element(Object key, Object value, int timeToIdleSeconds, int timeToLiveSeconds)
  {
    this(key, value);
    setTimeToIdle(timeToIdleSeconds);
    setTimeToLive(timeToLiveSeconds);
  }

      

五、Ehcache的统计配置和说明:

 

参考:http://carlosfu.iteye.com/blog/2237387

 

六、Ehcache的常用的eviction算法:

LRU(Least Recently Used): 默认

LFU(Least Frequently Used): 

FIFO(First In First Out):

 

七、MaxEntries和MaxBytes配置选择问题:

 

 

MaxEntries和MaxBytes,一般来说是不共用的。
如果能预估对象个数,但是容量不确定,可以用MaxEntries
如果能预估容量,但是对象个数不确定,可以用MaxBytes

  

八、哪些配置参数可以运行时动态修改

timeToLive,

timeToIdle,

maxEntriesLocalHeap,

maxBytesLocalHeap,

memory-store eviction policy, 

CacheEventListener可以动态增删

九、Ehcache批量操作优化:

虽然ehcache或者bigmemory都是微秒级别的,但是仍然可以使用批量操作提高效率。

 

void putAll(Collection elements)
Map getAll(Collection keys)
void removeAll(Collection keys)
 

 

十、是否要使用磁盘

一般来说,不建议使用,原因有如下几点:

  1. ehcache或者bigmemory一般是作为cache使用(高速),后端一般还有别的数据源顶着(redis hbase elasticsearch),如果加了磁盘会影响速度和未知因素,
  2. 如果没有硬盘的配置能大大简化配置
  3. 从计算机的发展趋势看,硬盘是一个瓶颈。

 

十一、Element生命周期

Flush – To move an entry to a lower tier. Flushing is used to free up resources while still keeping data in Ehcache .(将数据从高层刷到低层,例如heap->offheap): 保持高层数据量和容量
Fault – To copy an entry from a lower tier to a higher tier. Faulting occurs when data is required at a higher tier but is not resident there. The entry is not deleted from the lower tiers after being faulted.(将数据从低层刷到高层,例如offheap->heap):高层需要更热点的数据
Eviction – To remove an entry from Ehcache. The entry is deleted; it can only be reloaded from an outside source. Entries are evicted to free up resources.(将数据剔除,保持数据量和容量)
Expiration – A status based on Time-To-Live and Time-To-Idle settings. To maintain performance, expired entries may not be immediately flushed or evicted.(过期,不会立即flush or evicted,ehcache对于过期有自己的策略)
Pinning – To keep data in memory indefinitely.(强制数据保留在某一层)

  

十二、序列化问题

之前提过:Bigmemory的主要开销:序列化+sizeOf计算。

如果序列化对象过大(例如100k以上),会消耗CPU,因为序列化和反序列化是依靠CPU计算的,因此会对性能有很大影响。

  • BigMemroy系列文章--12. Ehcache和BigMemory常见问题_第2张图片
  • 大小: 43 KB
  • 查看图片附件

你可能感兴趣的:(bigmemory,sizeof,ehcache,copyonread,eviction)