Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式
目 录
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脚本编译引擎使用过程内存增涨与稳定的方式的更多相关文章
- 【JS】js引擎执行过程
概述 js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段,上篇文章我们介绍了语法分析和预编译阶段,那么我们先做个简单概括,如下: 语法分析: 分别对加载完成的代码块进行语法检验,语法正 ...
- 转:Android开发实践:用脚本编译Android工程
转自: http://ticktick.blog.51cto.com/823160/1365947 一般情况下,我们都是使用Eclipse+ADT插件或者Android studio软件来编译Andr ...
- 关于模板中的动态取值 ---反射与javascript脚本编译
在项目中经常遇到一个问题,打印word或者打印excel的时候,我们经常使用一对一的赋值或者批量替换的方式来对模板进行修改. 但是现在遇到两种场景: 1.取值是通过自定以方法进行取值的. 如:一个销售 ...
- SystemTap----将SystemTap脚本编译成内核模块
当运行SystemTap脚本时,会根据脚本生成一个内核模块,然后插入到系统中执行后退出.这个过程总共分为5个阶段:parse, elaborate, translate, compile, run ...
- unity3d 特殊文件夹和脚本编译顺序
unity3d 特殊文件夹和脚本编译顺序 转自http://blog.csdn.net/u010019717/article/details/40474631 大多数情况下,您可以选择任何你喜欢的文件 ...
- android的编译和运行过程深入分析
android的编译和运行过程深入分析 作者: 字体:[增加 减小] 类型:转载 首先来看一下使用Java语言编写的Android应用程序从源码到安装包的整个过程,此过程对了解android的编译和运 ...
- 通过ant脚本编译打包android工程
通过ant脚本,编译打包android工程 1.Android程序编译.打包.签名.发布的三种方式: 方式一:命令行手动编译打包 方式二:使用ant自动编译打包 方式三:使用eclipse+AD ...
- Cocos2d-x使用Luajit将Lua脚本编译成bytecode,启用加密
http://www.cocoachina.com/bbs/read.php?tid=205802 lua脚本进行加密,查了一下相关的资料 ,得知lua本身能够使用luac将脚本编译为字节码(byte ...
- 把perl脚本编译成exe
来源:http://www.veryhuo.com/a/view/38338.html 今天想把 perl 脚本编译成 exe 以便脱离 perl 解释器独立运行.都可以生成PERL的PE文件,在PE ...
随机推荐
- HCNA Routing&Switching之PPPoE协议
前文我们了解了广域网中的HDLC和PPP协议相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15174240.html:今天我们来聊一聊PPPoE协议相 ...
- 题解 P5038 [SCOI2012]奇怪的游戏
题解 题目 做这题之前,做了一道叫星际战争的题,很容易想到二分 \(+\) 网络流,那么二分啥呢? 我们先推一下式子,因为是对相邻格子加数,那么可以联想到黑白染色类问题. 设有黑色格子 \(B\) 个 ...
- 题解 e
传送门 第一眼看貌似可以树剖,然而那个绝对值不知怎么维护 求最小连通块我只会\(k^2\) 主席树貌似可以用来查询区间内与某个数差的绝对值的最小值? 确实,每次查大于等于该数的最小数和小于等于该数的最 ...
- Specification使用in
//是否包含下级授权点 1 包含 2 不包含 List<AuthorizationPoint> authList = null; List<Long> pointIdList ...
- 什么是.NET CLI CLR IL JIT GC,它们是如何工作的
参考网址: https://cloud.tencent.com/developer/article/1432891 1:什么是.NET? NET 是 Microsoft 的用以创建 XML Web 服 ...
- C语言 使用char字符实现汉字处理
系统:windows 64 编译器:gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 文本编辑器:notepa ...
- log4j.properties配置文件及详解
log4j配置文件有三个主要的组件:Logger,Appender和Layout,分别为日志类型,日志输出目的地,日志输出格式. 1. 配置日志级别及appenderName log4j.rootLo ...
- git所遇到的问题
出现这种情况,或 ERROR: Repository not found. fatal: 无法读取远程仓库. 解决办法如下: 1.先输入$ git remote rm origin(删除关联的orig ...
- 移动端常用单位——rem
移动端常用单位: ①px:像素大小,固定值 ②%:百分比 ③em(不常用,但是在首行缩进时可以使用):相对自身的font大小(当自身的字体大小也是em做单位时,才会以父元素的字体大小为基准单位) ④r ...
- 在已有Win7/10系统电脑中加装Ubuntu18.04(安装双系统)
准备一台有Win7/10的电脑. 为Ubuntu预留硬盘空间.最好在硬盘最后保留一个空闲分区.(Ubuntu会自动安装到后面的空闲分区) 用Universal USB Installer制作安装盘(U ...