码迷,mamicode.com
首页 > 其他好文 > 详细

看看大对象是如何爆你的内存

时间:2017-04-15 20:36:36      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:++   ram   pac   json   json.js   names   rand   div   action   

之前一直没注意到.net大对象的存在,直到这次api服务器内存爆满,经常性抽风几十秒才有响应,网站转化率急剧下降。

老板很重视,压力灰常大,这不周末还要加班,经过排查感觉是大对象导致的,在.net中,超过85000byte的对象垃圾回收时只标记删除不会移动。想写个demo验证一下,本以为很简单没想到竞费了一番功夫才实现,特此记录。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LargeObjectTest
{
    class Program
    {
        static object _lockobj = new object();
        static Random ran = new Random(DateTime.Now.Second);

        static void Main(string[] args)
        {
            var running = true;

            int count = 10 * 10000;


            //批量制造大对象
            Parallel.For(0, count, (c) =>
            {
                if (!running)
                    return;
                var s = Task.Run(() =>
                 {
                     if (!running)
                         return null;
                     lock (_lockobj)
                     {
                         var length = (int)((ran.NextDouble()) * 85 * 1024 * 737.6);//随机大于85000byte的数组
                         var obj = new byte[length];
                         for (var i = 0; i < length; i++)
                         {
                             obj[i] = (byte)ran.Next(33, 125);
                             if (!running)
                                 return null;
                         }
                         return Newtonsoft.Json.JsonConvert.SerializeObject(obj);
                     }
                 }).Result;


                Console.WriteLine(count);
                Console.WriteLine(s);
                Console.WriteLine("*****************************************************************");
                Console.WriteLine();
                Console.WriteLine();


                //GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
                GC.Collect();

            });

            Console.WriteLine("按任意键终止运行");
            Console.Read();
            running = false;

        }


    }
}

 

要点:

  1. 对象大小不要一样,否则没法产生内存碎片
  2. 要在多线程下运行,否则也没产生碎片(或者几率小)
  3. 最重要的是数组弄大点不然想爆满不知要等到哪一年

 

结论是:不要随便序列化你的大对象,不要随便重复序列化你的大对象,不要随便重复序列化你的随机大对象。前提当然是web环境了,本地程序应该不会有人抽风那么做吧,想那么做也比较难,不然你改改上面的代码试试。

当然我不会告诉你谁的错(我是不会出卖我前老板的)。

 

看看大对象是如何爆你的内存

标签:++   ram   pac   json   json.js   names   rand   div   action   

原文地址:http://www.cnblogs.com/yym/p/6715194.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!