Entity Framework 内存耗用太高,CPU耗用太高

gangAndgang 2014-06-26 12:07:04
目前公司在线运行的一个系统,后端采用Entity Framework,整个系统大概有50张表,每表字段数少的有3-5个,多个20-30个。
在生产环境运行中,发现内存占用很高,一启动就几百M,运行一段时间后,就达到7、800M,然后经常CPU100%,经过检测发现CPU100%时,一般都是在做GC回收。

查阅网上很多文章,发现是由于Entity Framework的缓存机制引起内存占用及GC回收造成CPU高。
比如:http://social.msdn.microsoft.com/Forums/zh-CN/d82d82be-f128-49cb-b09f-1fff982776ce/entity-framework

这个有什么办法解决吗
...全文
11047 64 打赏 收藏 转发到动态 举报
写回复
用AI写文章
64 条回复
切换为时间正序
请发表友善的回复…
发表回复
JLSliuyang 2016-05-13
  • 打赏
  • 举报
回复
下了个源码,能编译,但不能调试,微软真恶心!EF就是渣!还不如用MYSQL自带的连接库或连接器,写两句SQL就能搞定的事情,装个逼,搞个什么框架,什么面像对象,这么复杂干嘛?
zhiming99 2016-05-11
  • 打赏
  • 举报
回复
https://msdn.microsoft.com/zh-cn/magazine/dn532202.aspx 看看这个,或许有用
熊仔其人 2015-12-30
  • 打赏
  • 举报
回复
各位大神辩论的都很有道理,很精彩。请大家帮我看看这个代码,指点指点需要改进的地方,怎么改,谢谢 这是DAL层里面的一个根据参数对象,适配查询条件,并且适配排序,执行分页,获取列表结果的方法:

/// <summary>
        /// Get List By PageParameter
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public IEnumerable<academicnews> GetList(AcademicnewsParameter parameter)
        {
            var db = new TestdbEntities();
            var list = db.academicnews.AsQueryable();

            if (string.IsNullOrEmpty(parameter.OrderBy))
            {
                parameter.OrderBy = "nid";
                parameter.IsAsc = false;
            }

            #region 查询参数
            if (!string.IsNullOrEmpty(parameter.classcode))
            {
                list = list.Where(x => x.classcode.Equals(parameter.classcode));
            }
            if (parameter.type > 0)
            {
                list = list.Where(x => x.type == parameter.type);
            }

            if (parameter.sort > 0)
            {
                list = list.Where(x => x.sort == parameter.sort);
            }

            if (parameter.isvisible)
            {
                list = list.Where(x => x.isvisible == true);
            }
            else
            {
                list = list.Where(x => x.isvisible != true);
            }

            if (parameter.isdelete)
            {
                list = list.Where(x => x.isdelete == true);
            }
            else
            {
                list = list.Where(x => x.isdelete == false || x.isdelete == null);
            }

            if (!string.IsNullOrEmpty(parameter.title))
            {
                list = list.Where(x => x.title.Contains(parameter.title));
            }

            #endregion 查询参数
            return list.AsQueryable().GetPageList(parameter);
        }
分页方法如下:

    public static class ExtendEntity
    {
		/// <summary>
        /// 获取结果集总数,支持多字段排序,多个字段间用英文半角逗号分隔
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="query">结果集</param>
        /// <param name="parameters">页面参数</param>
        /// <returns></returns>
        public static IEnumerable<T> GetPageList<T>(this IQueryable<T> query, PageParameter parameters)
        {
           parameters.RecordCount = query.Count();
            if (!String.IsNullOrEmpty(parameters.OrderBy))
            {
                //query = query.DataSorting(parameters.OrderBy, parameters.IsAsc, true);

                //支持多字段排序
                string[] orderBys = parameters.OrderBy.Split(',');
                for (int i = 0; i < orderBys.Length; i++)
                {
                    string orderBy = orderBys[i];
                    bool isAsc = orderBy.StartsWith("-") ? false : (orderBy.StartsWith("+") ? true : parameters.IsAsc);
                    orderBy = orderBy.TrimStart('-').TrimStart('+');

                    query = query.DataSorting(orderBy, isAsc, i == 0 ? true : false);
                }
            }

            if (parameters.PageSize < 1)
                return query;

            if (parameters.PageIndex > 1)
                query = query.Skip((parameters.PageIndex - 1) * parameters.PageSize).Take(parameters.PageSize);
            return query.Take(parameters.PageSize).ToList();
        }

		/// <summary>
        /// 对数据结果集排序
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="source">结果集</param>
        /// <param name="orderBy">排序字段名称</param>
        /// <param name="IsASC">排序规则</param>
        /// <param name="isFirst"></param>
        /// <returns></returns>
        public static IQueryable<T> DataSorting<T>(this IQueryable<T> source, string orderBy, bool IsASC, bool isFirst)
        {
            var sortingDir = (isFirst ? "Order" : "Then") + (IsASC ? "By" : "ByDescending");

            ParameterExpression param = Expression.Parameter(typeof(T), orderBy);

            PropertyInfo pi = typeof(T).GetProperty(orderBy);
            Type[] types = new Type[2];
            types[0] = typeof(T);
            types[1] = pi.PropertyType;
            var lambda = Expression.Lambda(Expression.Property(param, orderBy), param);

            Expression expr = Expression.Call(typeof(Queryable), sortingDir, types, source.AsQueryable().Expression, lambda);
            IQueryable<T> query = source.AsQueryable().Provider.CreateQuery<T>(expr);
            return query;
        }
	
    }
实体模型继承的分页参数类型如下:

/// <summary>
	/// page parameter base class
	/// </summary>
	public class PageParameter
	{
		public int PageSize { get; set; }
		public int PageIndex { get; set; }
		public int RecordCount { get; set; }
		public string OrderBy { get; set; }
		public bool IsAsc { get; set; }
		public int PageCount
		{
			get
			{
				return RecordCount % PageSize > 0 ? (RecordCount / PageSize + 1) : RecordCount / PageSize;
			}
		}
	}
jetable 2014-10-18
  • 打赏
  • 举报
回复
看来EF真的很火,连大伙的争执都这么火,我们项目也一直在用,不知道是不是他引起的性能问题,反正项目运行不怎么快。平胸而论,EF肯定是性能比不上原生SQL,但是开发效率提高的那可不是一点点呀
凌戬 2014-09-30
  • 打赏
  • 举报
回复
请尝试在 Context 初始化时调用如下设置:
        protected void InitializeRepository()
        {
            ((IObjectContextAdapter)this).ObjectContext.ContextOptions.LazyLoadingEnabled = false;			
            ((IObjectContextAdapter)this).ObjectContext.ContextOptions.ProxyCreationEnabled = false;
            ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 300;

            this.Configuration.ValidateOnSaveEnabled = true;
            this.Configuration.AutoDetectChangesEnabled = true;
            this.Configuration.LazyLoadingEnabled = false;
        }
happydaily 2014-09-28
  • 打赏
  • 举报
回复
http://q.cnblogs.com/q/37952/ 看这个问题,两个用起来可能感觉一样,但EF实现却大不同,用Expression的会生成完整的SQL,而用Func的只生成部分SQL,后面的Where等等都是把数据放到内存里处理的,看你说的情况很像有这个问题。
happydaily 2014-09-28
  • 打赏
  • 举报
回复
你把有问题的代码发出来,大家帮你分析分析,
lijungui2008 2014-08-04
  • 打赏
  • 举报
回复
我用ef 都是只用他的 新增,修改,保存数据,查询直接用sql
  • 打赏
  • 举报
回复
不知道你的原因,内存高可以理解,但是cpu100%我觉得来不到ef的身上。只要你的程序正常,ef怎么会一直进行运算? 我之前的项目里用过两次ef,感觉还好,没有你说的这种问题。 建议还是想办法搞明白到底是执行了那部分程序导致了性能的损失
gangAndgang 2014-07-27
  • 打赏
  • 举报
回复
引用 51 楼 Going1981 的回复:
我公司有一个WPF、EF4.4的软件,跑在HP的瘦客户机上,确实比较吃内存,但CPU100%的情况基本没出现过。 有几个经验楼主姑且一听 1、最基本的,查询尽可能不要返回实体,而是用.select(new ...)选择只需要的列。 2、using 3、查询不做修改的数据把自动跟踪改变关掉 4、慎重使用延迟加载,比如类似于Company \ Department \ User 表,DataGrid绑定User集合,并且有一列绑定User.Department.Company,这时如果没关闭延迟加载,有多少个User就会执行多少次对Department和Company的查询,会卡得你哭 5、呃,把客户端的内存加大点 =。=
如果不返回实体,只是用select(new ...),这种写法,和直接写SQL差不多了吧
gangAndgang 2014-07-27
  • 打赏
  • 举报
回复
引用 53 楼 king283827940 的回复:
楼主问题解决了吗?分享下解决方案啊~
没办法。。。一直卡
king283827940 2014-07-26
  • 打赏
  • 举报
回复
楼主问题解决了吗?分享下解决方案啊~
qwertxp 2014-07-26
  • 打赏
  • 举报
回复
一揽子解决方案的东西,就意味着臃肿,缓慢。 看似什么都可以解决,实则什么都解决不好。特别是有效率需求的地方,更应该自己动手。 有些人不喜欢在代码中看到SQL语句,真是可笑的代码洁癖。 要是用代码生成的代码都和人写的一样好,咱们早该下岗了。
一只熊猫 2014-07-26
  • 打赏
  • 举报
回复
我公司有一个WPF、EF4.4的软件,跑在HP的瘦客户机上,确实比较吃内存,但CPU100%的情况基本没出现过。 有几个经验楼主姑且一听 1、最基本的,查询尽可能不要返回实体,而是用.select(new ...)选择只需要的列。 2、using 3、查询不做修改的数据把自动跟踪改变关掉 4、慎重使用延迟加载,比如类似于Company \ Department \ User 表,DataGrid绑定User集合,并且有一列绑定User.Department.Company,这时如果没关闭延迟加载,有多少个User就会执行多少次对Department和Company的查询,会卡得你哭 5、呃,把客户端的内存加大点 =。=
gangAndgang 2014-07-22
  • 打赏
  • 举报
回复
引用 49 楼 csz_1987 的回复:
[quote=引用 48 楼 stonefeng 的回复:] [quote=引用 47 楼 csz_1987 的回复:] 表示关注,刚对EF开始感兴趣,就听到这一噩耗。
nhibernate可以用的,只不过不是微软官方支持。在java领域,这个hibernate很火的。[/quote] 知道。但是配置比较复杂,上手没EF快。 总觉得不该啊,微软怎么会自己坑自己呢。。。。[/quote] 其实一切ORM都是鸡肋,说得很好听,但用起来就是渣渣,很早的一篇文章就有讨论过这方面的事 http://segmentfault.com/a/1190000000378827
csz_1987 2014-07-21
  • 打赏
  • 举报
回复
引用 48 楼 stonefeng 的回复:
[quote=引用 47 楼 csz_1987 的回复:] 表示关注,刚对EF开始感兴趣,就听到这一噩耗。
nhibernate可以用的,只不过不是微软官方支持。在java领域,这个hibernate很火的。[/quote] 知道。但是配置比较复杂,上手没EF快。 总觉得不该啊,微软怎么会自己坑自己呢。。。。
疯癫行者 2014-07-17
  • 打赏
  • 举报
回复
引用 47 楼 csz_1987 的回复:
表示关注,刚对EF开始感兴趣,就听到这一噩耗。
nhibernate可以用的,只不过不是微软官方支持。在java领域,这个hibernate很火的。
csz_1987 2014-07-17
  • 打赏
  • 举报
回复
表示关注,刚对EF开始感兴趣,就听到这一噩耗。
qq_17201303 2014-07-03
  • 打赏
  • 举报
回复
引用 7 楼 moonwrite 的回复:
我看过一些程序员随便就ToList什么的~ 我就会跟他说~ 在你还没有分页前就ToList~ 那是将整个表的数据加载啊~ 如果你正确地使用EF~而它还是占用七八百~我觉得没有问题罗~ 等你明白缓存这个概念~你就明白这些消耗很值得的 对应使用EF~ 你要很明确你写的linq 那些写法是会产生sql去查询~ 那种写法是从数据库加载数据~ 性能低一倍~~开发速度快2~3倍~ 值得~ 你最好贴出点增删改查的~然我们看看有什么问题~ 还有EF是否被你写成静态或单例~ 这些都是很可怕的
我觉得是这个问题
足球中国 2014-06-29
  • 打赏
  • 举报
回复
引用 44 楼 darkinger 的回复:
一群人,真的以为自己很行了,站着说话不腰痛,别人提出EF有问题就接受不了,可事实摆在眼前,贴子里也给出一个很简单的例子,请所谓懂程序开发的人来测试与分析一下这个例子吧。
蛋定蛋定。
加载更多回复(43)

17,740

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧