目       录

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. NOIP 模拟 $19\; \rm v$

    题解 一道概率与期望的状压题目 这种最优性的题目,我们一般都是倒着转移,因为它的选择是随机的所以我们无法判断从左还是从右更有,所以我们都搜一遍 时间一定会爆,采用记忆化搜索,一种状态的答案一定是固定的 ...

  2. C#多线程实践-锁和线程安全

    锁实现互斥的访问,用于确保在同一时刻只有一个线程可以进入特殊的代码片段,考虑下面的类: class ThreadUnsafe { static int val1, val2; static void ...

  3. leaflet antvPath示例

    参考:https://www.cnblogs.com/vichang/p/9438870.html leaflet-antvPath官网:https://github.com/rubenspgcava ...

  4. Java静态内部类——重点是精妙的demo

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/cd18333612683/article/details/79129503什么是内部类大部分时候,类 ...

  5. Git使用:

    配置可参考: 配置name 及email:$ git config --global user.name "Your Name"$ git config --global user ...

  6. MFC 绘制坐标系

    主要讨论映射模式:MM_ANISOTROPIC,MM_ISOTROPIC.及相关方法的应用. 1,先建立一个MFC单文档,过程不再赘述. 2,在View类中找到CMainFrame::PreCreat ...

  7. win系统打不开CHM文件(例如JDK的API)

    打开文件乱码,打开时弹出乱码 前提说明,存放路径不得有中文,文件名也不能有中文 检查下面三个文件:    hh.exe文件放置电脑 C:\Windows目录下:     hhctrl.ocx ,its ...

  8. Centos7.4 安装MySQL 5.7.21 (通用二进制包)

    1.下载安装包 MySQL 官方下载地址:https://dev.mysql.com/downloads/mysql/ MySQL 5.7官方安装文档:https://dev.mysql.com/do ...

  9. sizeof关键字

    sizeof关键字 sizeof不是函数,所以不需要包含任何头文件,它的功能是计算一个数据类型的大小,单位为字节 sizeof的返回值为size_t size_t类型在32位操作系统下是unsigne ...

  10. JavaScript——数组——数组长度

    JavaScript--数组--数组长度 JavaScript中的数组长度是可变的,可用赋值运算符改变数组大小,如果改变之后的数组的长度比原数组大,则新数组会在末尾补充相应数量的空位,空位上的数组元素 ...