zoukankan      html  css  js  c++  java
  • 看看大对象是如何爆你的内存

    之前一直没注意到.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环境了,本地程序应该不会有人抽风那么做吧,想那么做也比较难,不然你改改上面的代码试试。

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

  • 相关阅读:
    make输出全部重定向到文件
    python selenium-webdriver 元素定位(三)
    通过vmware 启动cloudera-quickstart-vm-5.10.0-0-vmware.zip镜像无法启动。
    编写第一个python selenium-webdriver程序(二)
    sublime Text3 新建文件时定义模块
    python selenium-webdriver 环境搭建(一)
    gitlab 添加SSH Key
    python 使用 'python -m pip install --upgrade pip'提示PermissionError: [WinError 5] 拒绝访问
    bitnami gitlab 配置域名
    bitnami gitlab 安装
  • 原文地址:https://www.cnblogs.com/yym/p/6715194.html
Copyright © 2011-2022 走看看