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 ...
随机推荐
- 常见web中间件漏洞(五)weblogic漏洞
继续整理有关中间件漏洞思路(仅做简单思路整理,不是复现,复现请参考大佬们的长篇好文,会在文章中列举部分操作) WebLogic是Oracle公司出品的一个application server,确切的说 ...
- Go的Channel发送和接收
先来看一道面试题: 对已经关闭的 chan 进行读写,会怎么样?为什么? 在上一篇学习 Go 协程的文章中,知道 go 关键字可以用来开启一个 goroutine 进行任务处理,但多个任务之间如果需要 ...
- mongodb(docker-compose)
version: '3.1' services: mongo: image: mongo restart: always environment: MONGO_INITDB_ROOT_USERNAME ...
- map中使用箭头函数遇到的坑
箭头函数提供了更简洁和更短的语法,其中一个可用功能是可以将函数编写为具有隐式返回值的lambda表达式.这对于功能样式代码很方便,比如使用函数映射数组: const numbers = [1,2,3, ...
- WPF学习笔记二 依赖属性实现原理及性能分析
在这里讨论依赖属性实现原理,目的只是学习WPF是怎么设计依赖属性的,同时更好的使用依赖属性. 首先我们来思考一个简单的问题:我们希望能验证属性的值是否有效,属性变更时进行自己的处理.回顾一下.net的 ...
- 【转】分布式之redis复习精讲
转自:https://www.cnblogs.com/rjzheng/p/9096228.html 引言 为什么写这篇文章? 博主的<分布式之消息队列复习精讲>得到了大家的好评,内心诚惶诚 ...
- 轻松入门vue系列
一.vue基础语法 二.vue组件化开发 三.Vue前后端交互 四.vue前端路由 喜欢不要忘了点个赞哟
- jQuery中获取属性值:attr()、html()、text()、val()等(一)
<!DOCTYPE html> <html> <head> <title>01_basic.html</title> <meta na ...
- sparksql解析流程
1.sparkSql处理核心:Catalyst工作流程(本质:把sql.dataframe相结合,以树tree的形式来存储.优化) 2.catalyst工作流程 1)Parser(解析器):SqlPa ...
- HCNP Routing&Switching之OSPF虚连接
前文我们了解了OSPF的网络类型.帧中继交换机映射以及路由器帧中继映射相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15195762.html:今天我 ...