zoukankan      html  css  js  c++  java
  • 缓存大对象

    有时候,我们想要把一些大对象缓存起来,因为产生一次大对象的代价很大,我们需要产生一次,尽可能的多次使用,从而提升响应。

    提到大对象,这里就很有必要对其进行一个比较深入的介绍了。在.NET中,所谓的大对象,就是指的其占用的内存大于了85K的对象,下面通过一个比较将问题说清楚。

    如果现在有一个Person类的集合,定义为List<Person>,每个Person对象占用1K的内存,如果这个Person集合中包含了100个Person对象实例,那么这个集合是否是大对象呢?

    回答是:不是!

    因为集合中只是包含的Person对象实例的引用而言,即,在.NET的托管堆上面,这个Person集合分配的内存大小也就是100个引用的大小而言。

    然后,对于下面的这个对象,就是大对象了: byte[] data = new byte[87040](85 * 1024 = 87040)。

    说到了这里,那就就谈谈,为什么说:产生一次大对象的代价很大。

    因为在.NET中,大对象是分配在大对象托管堆上面的(我们简称为“大堆”,当然,还有一个对应的小堆),而这个大堆上面的对象的分配机制和小堆不 一样:大堆在分配的时候,总是去需找合适的内存空间,结果就是导致出现内存碎片,导致内存不足!我们用一个图来描述一下,如图5所示:

    上图非常明了,在图5中:

    • 垃圾回收机制不会在回收对象之后压缩大堆(小堆是压缩的)。
    • 分配对象的时候,需要去遍历大堆,去需找合适的空间,遍历是要花成本的。
    • 如果某些空间小于85K,那么就不能分配了,只能白白浪费,也导致内存碎片。

    讲完了这些之后,我们言归正传,来看看大对象的缓存。

    正如之前讲过,将对象缓存和读取的时候是要进行序列化与反序列化的,缓存的对象越大(例如,有1M等),整个过程中就消耗更多的CPU。

    对于这样的大对象,要看它使用的是否很频繁,是否是公用的数据对象,还是每个用户都要产生的。因为我们一旦缓存了(特别在分布式缓存中),就需要同 时消耗缓存服务器的内存与应用程序服务器的CPU。如果使用的不频繁,建议每次生成!如果是公用的数据,那么建议多多的测试:将生产大对象的成本与缓存它 的时候消耗的内存和CPU的成本进行比较,选择成本小的!如果是每个用户都要产生的,看看是否可以分解,如果实在不能分解,那么缓存,但是及时的释放!

  • 相关阅读:
    dp 简单例题poj 1260 Pearls
    多校赛 Barareh on Fire
    中国剩余定理的简单应用 poj 1006 Biorhythms
    CF 5A. Chat Server's Outgoing Traffic
    springmvc使用aop心得
    Firefox添加插件支持修改Headers
    提高网站打开速度的18点要素
    用maven打包项目成war文件
    springmvc使用@ResponseBody返回json乱码解决方法
    用JS实现删除买家信息(阿里巴巴模拟笔试)
  • 原文地址:https://www.cnblogs.com/shihao/p/2451572.html
Copyright © 2011-2022 走看看