目       录

1.      引用程序集... 1

2.      内存增涨的情况... 2

3.      内存稳定的情况... 4

1.   引用程序集

Roslyn 是微软公司开源的 .NET 编译器。编译器支持 C# 和 Visual Basic 代码编译,并提供丰富的代码分析 API。使用非常方便,增加引用脚本编译引擎程序集:Microsoft.CodeAnalysis.CSharp.Scripting.dll,如下图:

但是在使用过程中会出现内存增涨的情况,如果要解决这个问题,需要对代码进行结构化处理。下面演示内存增涨和稳定两种情况。

2.   内存增涨的情况

  直接使用内部的API接口:CSharpScript.EvaluateAsync,完整代码如下:

using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting; namespace ConsoleApp1
{
public class Program
{
private static ScriptOptions scriptOptions=ScriptOptions.Default.WithEmitDebugInformation(false);
private static string script="int num=1+2;Write(num);return num;";
private static Custom custom = new Custom();
static void Main(string[] args)
{
while(true)
{
MemoryRise(); Thread.Sleep(10);
}
} //内存内涨
public static void MemoryRise()
{
object result = CSharpScript.EvaluateAsync(script,scriptOptions,custom,typeof(Custom)).Result; if(result!=null)
{
Console.WriteLine(DateTime.Now.ToString ()+" Result:"+result.ToString ()); }
}
} public class Custom
{
public void Write(int num)
{
Console.WriteLine("Custome.Write:"+num.ToString());
}
}
}

在调试代码的过程,每次执行代码会把代码生成一个新的程序集模块,并且在新的程序域中加载,没有找到卸载程序域和模块的方法。如下图:

正式运行编译好的程序集,内存明显增涨的比较快。如下图:

3.   内存稳定的情况

  要避免对相同代码进行反复编译和加载模块,需要对代码进行特殊处理。代码如下:

using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting; namespace ConsoleApp1
{
public class Program
{
private static ScriptOptions scriptOptions=ScriptOptions.Default.WithEmitDebugInformation(false);
private static Script baseScript = CSharpScript.Create("", options: scriptOptions, globalsType: typeof(Custom));
private static Dictionary<string, Script<object>> loadScriptCache = new Dictionary<string, Script<object>> ();
private static string script="int num=1+2;Write(num);return num;";
private static Custom custom = new Custom(); static void Main(string[] args)
{
while(true)
{
MemoryNormal(); Thread.Sleep(10);
}
} //内存稳定
public static void MemoryNormal()
{
if (!loadScriptCache.ContainsKey(script))
loadScriptCache.Add(script, baseScript.ContinueWith<object>(script)); ScriptState<object> scriptState = loadScriptCache[script].RunAsync(custom).Result; if(scriptState.ReturnValue!=null)
{
Console.WriteLine(DateTime.Now.ToString ()+" Result:"+scriptState.ReturnValue.ToString ());
}
}
} public class Custom
{
public void Write(int num)
{
Console.WriteLine("Custome.Write:"+num.ToString());
}
}
}

只会编译和加载一次相同代码的程序集模块,编译调试过程如下图:

正式运行编译好的程序集,运行一段时间,内存稳定在80多MB。如下图:


物联网&大数据技术 QQ群:54256083
物联网&大数据项目 QQ群:727664080
网站:http://www.ineuos.net
QQ:504547114
微信:wxzz0151
博客:https://www.cnblogs.com/lsjwq
微信公众号:iNeuOS
 

Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式的更多相关文章

  1. 【JS】js引擎执行过程

    概述 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍了语法分析和预编译阶段,那么我们先做个简单概括,如下: 语法分析: 分别对加载完成的代码块进行语法检验,语法正 ...

  2. 转:Android开发实践:用脚本编译Android工程

    转自: http://ticktick.blog.51cto.com/823160/1365947 一般情况下,我们都是使用Eclipse+ADT插件或者Android studio软件来编译Andr ...

  3. 关于模板中的动态取值 ---反射与javascript脚本编译

    在项目中经常遇到一个问题,打印word或者打印excel的时候,我们经常使用一对一的赋值或者批量替换的方式来对模板进行修改. 但是现在遇到两种场景: 1.取值是通过自定以方法进行取值的. 如:一个销售 ...

  4. SystemTap----将SystemTap脚本编译成内核模块

      当运行SystemTap脚本时,会根据脚本生成一个内核模块,然后插入到系统中执行后退出.这个过程总共分为5个阶段:parse, elaborate, translate, compile, run ...

  5. unity3d 特殊文件夹和脚本编译顺序

    unity3d 特殊文件夹和脚本编译顺序 转自http://blog.csdn.net/u010019717/article/details/40474631 大多数情况下,您可以选择任何你喜欢的文件 ...

  6. android的编译和运行过程深入分析

    android的编译和运行过程深入分析 作者: 字体:[增加 减小] 类型:转载 首先来看一下使用Java语言编写的Android应用程序从源码到安装包的整个过程,此过程对了解android的编译和运 ...

  7. 通过ant脚本编译打包android工程

    通过ant脚本,编译打包android工程 1.Android程序编译.打包.签名.发布的三种方式:  方式一:命令行手动编译打包  方式二:使用ant自动编译打包  方式三:使用eclipse+AD ...

  8. Cocos2d-x使用Luajit将Lua脚本编译成bytecode,启用加密

    http://www.cocoachina.com/bbs/read.php?tid=205802 lua脚本进行加密,查了一下相关的资料 ,得知lua本身能够使用luac将脚本编译为字节码(byte ...

  9. 把perl脚本编译成exe

    来源:http://www.veryhuo.com/a/view/38338.html 今天想把 perl 脚本编译成 exe 以便脱离 perl 解释器独立运行.都可以生成PERL的PE文件,在PE ...

随机推荐

  1. 常见web中间件漏洞(五)weblogic漏洞

    继续整理有关中间件漏洞思路(仅做简单思路整理,不是复现,复现请参考大佬们的长篇好文,会在文章中列举部分操作) WebLogic是Oracle公司出品的一个application server,确切的说 ...

  2. Go的Channel发送和接收

    先来看一道面试题: 对已经关闭的 chan 进行读写,会怎么样?为什么? 在上一篇学习 Go 协程的文章中,知道 go 关键字可以用来开启一个 goroutine 进行任务处理,但多个任务之间如果需要 ...

  3. mongodb(docker-compose)

    version: '3.1' services: mongo: image: mongo restart: always environment: MONGO_INITDB_ROOT_USERNAME ...

  4. map中使用箭头函数遇到的坑

    箭头函数提供了更简洁和更短的语法,其中一个可用功能是可以将函数编写为具有隐式返回值的lambda表达式.这对于功能样式代码很方便,比如使用函数映射数组: const numbers = [1,2,3, ...

  5. WPF学习笔记二 依赖属性实现原理及性能分析

    在这里讨论依赖属性实现原理,目的只是学习WPF是怎么设计依赖属性的,同时更好的使用依赖属性. 首先我们来思考一个简单的问题:我们希望能验证属性的值是否有效,属性变更时进行自己的处理.回顾一下.net的 ...

  6. 【转】分布式之redis复习精讲

    转自:https://www.cnblogs.com/rjzheng/p/9096228.html 引言 为什么写这篇文章? 博主的<分布式之消息队列复习精讲>得到了大家的好评,内心诚惶诚 ...

  7. 轻松入门vue系列

    一.vue基础语法 二.vue组件化开发 三.Vue前后端交互 四.vue前端路由 喜欢不要忘了点个赞哟

  8. jQuery中获取属性值:attr()、html()、text()、val()等(一)

    <!DOCTYPE html> <html> <head> <title>01_basic.html</title> <meta na ...

  9. sparksql解析流程

    1.sparkSql处理核心:Catalyst工作流程(本质:把sql.dataframe相结合,以树tree的形式来存储.优化) 2.catalyst工作流程 1)Parser(解析器):SqlPa ...

  10. HCNP Routing&Switching之OSPF虚连接

    前文我们了解了OSPF的网络类型.帧中继交换机映射以及路由器帧中继映射相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15195762.html:今天我 ...