【看了请推荐,推荐满100后,将发补丁地址】php
Xamarin项目从喊口号到如今,好几个年头了,在内地没有火起来,缘由无非有三,1.受权费贵 2.贵 3.原生态Java开发Android的愈来愈多,人工费用成本下降。html
上面说的3条,都跟钱相关,不占技术边,看起来跟本文的标题严重不符。可是,细细看来,若是这个产品的圈子打不开,再牛的技术,也是枉然。由于技术是在不断推动的,java
性能问题,技术问题,实现问题,等等均可以随着时间的推进去解决,可是,Xamarin公司貌似没打算把价格下降。愈加的稳定。死鬼死鬼.......。因此,咱们须要破解,咱们须要破解,咱们须要破解(重要的事情说3遍),可是破解并不是容易,这个平台软件,几乎是我见过的CLI语言最难破解的东东,由于里面钉子太多,剃不干净。(我曾经尝试去破解,发现须要耗费太多的时间,并且不稳定)。。可是,嗯,道高一尺魔高一丈。找补丁,到谷歌..........如今能够明确的告诉你们,最新版的Xamarin有了破解补丁。谷歌去吧。android
上面说的是题外话,但愿这个生态能够在这片土壤继续壮大。咱们开始进入咱们的标题,不要说我是标题党。呵呵。安全
咱们就讨论Xamarin的Android开发机制吧,IOS的,自己就是在MAC下面编译的,是AOT,不是JIT.........AOT机制,自己把代码转换成了Native代码应用。JIT是基于虚拟机语言运行的中间代码。Java和.Net 都是JIT 。。。。都有相似运行的虚拟机。Java->JVM .....C#->CLR->JIT->Native Code......微信
首先,这个跨平台的思路是基于好久之前的的Mono项目,关于Mono项目,本身百度脑补。Mono是对微软.Net的跨平台的实现。基于C语言的实现,能够实现CLR在不一样的平台系统下的运行。固然,针对的就是Linux系统。Mono的诞生,让.net能够在Linux下跑了。框架
好,上面仅仅是开端,咱们再来看下Android。这个项目是Google收购的一家Droid公司的产品。就是用开源的Linux系统,作的二次开发。本质依然是Linux内核。异步
谷歌收购这个项目后,加大了对这个项目的投入。最终得以让这个项目在移动设备上运行起来。。(资本+科技=进步)ide
看Android项目的结构图:wordpress
从最上层的应用层,如 短信 电话 视频 微信 QQ等应用 到先的支持库,都是用Java实现的。
再往下就是一些对硬件功能包装的库lib层,大可能是一些开源的Linux应用库,跟这个层平级的Android的虚拟机Dalvik。
最终是Linux的内核,系统的内核的做用,就是操做系统跟硬件进行交互。(固然,硬件须要对应的驱动被系统所能识别)
以上是安卓的结构和运行概述。当你打开微信的时候,就是从应用层-》框架层-》虚拟机到内核的一个来回调用交互。
----------------------------------Xamarin是怎么运行的?----------------------------------
咱们上面说过,Mono项目,实现.net语言在Linux下运行,Android是Linux项目,那只要Android中有Mono,那么.net 就能在安卓里跑!!!!
因而,从Mono开发过的一些人,过分到了Xamarin公司。Xamarin公司就是基于此。
那么Xamarin打包的安卓应用是怎么跑的? 看下面的图:
这是啥?
哦,老伯伯的皮影。
额,被老外学会了。。。。。
而后, 无语了...................
没错,这个Xamarin其实就是皮影戏(高科技的皮影)!!!!!!!!!!!!!!!!!!!!!
(写到这里,不只为国人悲哀,本身家的东西都被当垃圾丢弃,外国佬却总能从里面找出点什么。。。好比:炸药 司南 罗盘 等等,咱们本身抛弃了本身,咱们的眼里脑子里只有钱钱房房.................拿出点理想吧 my guys!!!)
说它是高科技的皮影,并不是空穴来风。咱们看看官方给出的结构解释:
原文:
大概意思是:Xamarin安卓项目是基于Mono运行时的,Android原生应用基于安卓运行时,也就是那个Dalvik虚拟机。。。当运行Xamarin建立的安卓应用的时候,
对应的安卓虚拟机上也会有对应包装过的对象的实例被分配。那个MCW 表明的是对原生Android的Lib的绑定,ACW是基于调用映射的API后返回响应到Mono。
怎么绑定,又怎么反馈呢?看官方怎么说的。。。
下文:
地址:http://developer.xamarin.com/guides/android/under_the_hood/architecture/
英文很差的同窗,本身打开网址找翻译工具吧。
大概意思是:MCW 的绑定机制还有ACW的核心就是 JNI 。
JNI是什么鬼?科普一下:JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其余语言的通讯(主要是C&C++)。
好,既然提供交互入口JNI,那么咱们的代码在通过monodroid处理后,就能够与Android这个java项目交互了。
那么C#语言是否是被处理转换成了JNI的应用了?是的。看图:
看完上图,你应该知道了,它在编译的时候,将C#代码文件,转化成了基于对Java原生文件的映射。注意:不是直接转化成了Java代码!是调用注册。
生产的java文件中并不提供运行实现,而是提供了在Android运行时的匹配映射!!!!!!!!!!!!!!!
真正的执行代码依然在classes.dex文件中。但并非咱们的C#编译的业务代码哦~~~业务代码一下子会说的哦(这个文件是二进制的可被安卓虚拟机执行的文件,跟语言无关)。
Java原生的开发会把业务代码压缩进此文件。这个文件也是安卓虚拟机执行对应的应用时候,能找到入口,起始点。可是,Mono项目的业务代码没在这个里面,记住,它是皮影戏。这个是皮影。真正的操做者,幕后凶手,在后台!!!
上法宝:
Xamarin生成的apk包中,也是这样。
lib目录提供了运行时须要的lib 库,如Mono运行时。
注意下面的那俩文件,就是皮影戏的杆儿,映射工具。
真正的执行代码在????
在 lib 中或者在assemblies中!!
为啥是或者?由于企业版的Xamarin,支持使用NDK将应用打包成Native应用!!!
有的人纠结那个calsses.dex文件,做为入口,说Android的应用不是非线性耦合的模块应用吗?是的,可是,这非线性针对的是系统,或者是程序块内部,而不是系统跟程序应用之间的描述。应用插入到系统上,那个自描述文件 AndroidManifest.xml 提供了程序的入口描述。
而calsses.dex被安卓虚拟机 Dalvik 执行后,会给这个程序分配对应的程序运行域,
你们注意第2点和第7点有助于咱们理解Xamarin.Android的工做机制
好,到此,你就知道了吧,那个classes.dex 就是给Zygote提供孵化器应用的............Zygote(受精卵。很形象。应用像是受精卵,经过他暖化出来了个小鸡应用)
KO!!!!!!!到此,你也就基本知道,这玩意儿是怎么运行的了吧。。。。没错,记住,皮影戏!!!!!!!!!!!!!!!
-----------------------------垃圾回收----------------------------------------
关于这个话题,其实不必过度讨论,由于既然是皮影戏,那么确定两边交互的时候 确定不如原生,若是你纠结这个,那么请学好Java去吧。
而后就是硬件的问题,从09年到如今,内存啊 CPU什么的再移动终端上换了好几代了。从单核到双核到四核到八核。。。。。硬件的提高简直是要亲命的。
花好几个月优化的项目,可能新一代的的硬件直接藐视了之前的项目性能问题。。。(固然,不能不关注性能。在一些游戏 视频等对硬件渲染要求较高的时候,就能体现出性能的致命性!!)
好了看到这里,你也不必继续往下看了。下面的是基于Xamarin的内存管理。
由于是皮影戏,两边实际上是互相持有对方的信息的。耍皮影的根据皮影反馈的信息,进行下一步如何操做,皮影接到命令,就会在屏幕上显示对应的动做。。。
摘抄:http://www.cnblogs.com/wintersun/archive/2013/02/28/2937270.html
1. 性能问题。例如垃圾回收,Mono for Android 声称支持垃圾回收,但也有须要注意的一些严重限制。"GC不完整视图的进程,可能没法运行在内存不足时,因为GC不知道内存不足。"由于这一般须要手动,每当建立一个activity运行垃圾回收或销毁,以释放未使用的内存。不然,可能致使内存不足的异常。 我本身也不止一次碰到了这个问题,不得不使用替代方法来解决问题。
关于内存管理:
许多Mono for Android被分配对象为包装Java对象作为它们的表明。 这时会发生什么:每次你分配一个包装过类型相对应Java类型,就建立两个对象:
1). Java对象在Java堆中
2). Mono代理对象在Mono堆中
Mono for Android不能确保这两个对象相互引用后长时间存活。那就是,Mono的垃圾回收引用一个对象,Java端的对象将一直活着,反之亦然。这个代理对象的建立mandroid.exe是工具编译时完成。 然而,GC是懒惰的,按需运行的集合,而不是简单地对象超出范围时候。 那么这意味着跨虚拟机的垃圾至少比通常更多,这是不可避免的。因此,为了临时使用时分配一个大数字对象,显示释放那些对象所需的资源是宝贵的。约定的方法使用using关键字来new一个object,使用using子句来隐式释放目标的new object是有必要的。释放Mono端的包装的Java-VM收集的对象,从而来防止太多的临时对象关联在一块儿很长时间。
去官方网站了解更多关于Mono for Android的垃圾回收。
其实,Mono已经对垃圾回收机制,一直在优化。
针对iOS的MonoTouch目前支持了分代式垃圾回收器(generational garbage collector)SGen。直到不久以前,Sgen还只是完整版本Mono中的一个实验性部分。伴随着垃圾回收器一同到来的,还有一个为iOS准备的 内存分析器(Memory Profiler),它能够从MonoDevelop集成开发环境中访问到。
分代式垃圾回收器Sgen取代了Mono中传统的Boehm垃圾回收器。虽然Sgen预计会有更好的性能,但其保守式扫描仍然会给它带来一些阻碍。预计未来Sgen会切换到精确的堆栈标记系统,这样应当能够大幅度减小产生的内存碎片。
iOS分析器支持两种模式,默认模式是堆分析模式,在该模式中内存快照能够根据须要或者触发器进行采集,而该触发器能够设置成必定数量的垃圾收集器周期或者基于时间的时间间隔。此外,该分析器还包含了一些标准工具,如对比快照和查找内存中的对象位置。
性能分析支持统计抽样,以及精确性虽佳但速度不足的进入/离开事件记录。统计抽样采集应用程序快照,并根据每一个方法被采集器抓取的频度对它们的速度 进行评估。从字面上看,进入/离开事件记录就是在函数每次开始或完成时记录一条日志。它虽然提供了时间花费的完整记录,但会带来严重的性能开销。这种模式 一样可以捕获与对象分配相关的堆栈跟踪。
MonoDevelop 2.8.5和MonoTouch 5.1.1都规定使用该工具。而对于个别项目,必须激活调试、分析和SGen垃圾回收器选项。
Sgen 项目一直在推动着。。。
关于怎么个机制,本身看官方文章吧。太长,不翻译了。
http://www.mono-project.com/docs/advanced/garbage-collector/sgen/
https://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/
院子里却是有点小资料,了解下就是了。
来自:http://www.cnblogs.com/shanyou/archive/2012/12/09/2810468.html
Mono 3如今是默认 GC是SGen 垃圾回收器,垃圾回收器几个性能和扩展性方面的改进,以更好地利用多核处理器硬件。SGen 已移植到 Windows 和 MIPS。
mono 最开始使用的是 Boehm-Demers-Wiser Conservative Garbage Collector ,mono 3.0以前的版本做为默认的垃圾收集器也是这个,Boehm垃圾收集器的主要问题在于没法精确读取寄存器与栈帧。由于没法肯定给定值究竟是指针仍是标量,所以它老是假设给定值是指针,而且将相关联的对象标记为存活状态。这么作不只会错误致使大块内存没法分配,同时还使得压缩可用空间这项工做变得异常艰难。
后来mono有了本身的 Simple Generational GC , 就是分代式垃圾回收器Sgen,取代了Mono中传统的 Boehm垃圾回收器。文档地址:http://www.mono-project.com/Compacting_GC,它使用精确的分代式(generational)垃圾收集器,相似于.NET版本的CLR。SGen垃圾收集器使用两生代而非.NET中的三个,但像.NET同样对于大对象使用独立的堆。
Mono 3.2进一步提高了SGen GC,特别是针对下面的场景——
Mono 3.0添加了异步支持、改进的SGen垃圾收集器及其余特性
SGen – Concurrency and Evacuation