Mono

Mono是一個由Xamarin公司（先前是Novell，最早為Ximian）所主持的自由開放源碼專案。該專案的目標是創建一系列符合ECMA標準（Ecma-334和Ecma-335）的.NET工具，包括C#編譯器和通用語言架構。與微軟的.NET Framework（共通語言執行平臺）不同，Mono項目不僅可以運行於Windows系統上，還可以運行於Linux、FreeBSD、Unix、OS X和Solaris，甚至一些遊戲平台，例如：Playstation 3、Wii或XBox 360。Mono的標誌是一個猴子格式的臉。

Mono現由Novell持有雙重許可，這和Qt和Mozilla Application Suite的情況相似。Mono的C#編譯器及其相關工具發布於GNU通用公共許可證（GPL）之下，其運行時庫發布於GNU寬通用公共許可證（LGPL）之下，其類庫發布於MIT許可證之下。這些均是開源協議因此Mono是一個開源軟體。

微軟開發了一個稱為通用語言架構（Shared Source Common Language Infrastructure，Shared Source CLI；即今ECMA—通用語言架構）的可用於FreeBSD，Windows和Mac OS X的.NET實現版本。微軟的共享原始碼協議並不是開源軟體協議，且可能對於社區來說也是不足夠的（它明文禁止了對軟體的商業用途）。另外，GNU也有一個.NET實現版本Portable.NET項目，該項目與Mono項目有著很多相同的目標。

Mono虛擬機包含一個即時編譯引擎，該引擎可用於如下處理器：x86、SPARC、PowerPC、ARM、S390（32位模式和64位模式）、x86-64、IA-64和64位模式的SPARC。該虛擬機可以將代碼編譯為本機代碼。

## 歷史

當Microsoft在2000年6月第一次公佈.NET Framework時，它被描述為一個以網際網路標準為基底的新的平台。並且在12月發表了基本的共通語言架構開放標準的形式（ECMA-335），提供了無相依性實作的可能。Ximian的米格爾·德伊卡薩在.NET的文檔於2000年10月發布時就馬上對.NET產生了興趣。在查看字節碼解釋器後，他發現對於元數據（metadata）沒有相應的說明文檔。2001年2月，德伊卡薩在.NET郵件列表中索要到了那段缺失了的關於元數據文件格式的資訊，並開始了採用C#編寫一個C#編譯器的工作，作為對C#的實踐。2001年4月ECMA公布了那段缺失的文件格式，而在GUADEC（2001年4月6日－4月8日）德伊卡薩展示了他的編譯器的一些特性（那個時候他的編譯可以解釋自身）。

Ximian內部對如何創建能有效提升生產效率的工具進行了大量的討論，他們的目標是通過這些創建出來的工具讓使用者可以在更短時間內創建出更多的應用程式從而縮短開發周期和降低開發成本。經過可行性研究後，他們清楚地見到創建這樣的一項技術是可行的，於是Ximian從其它的項目抽調人員並創建了Mono的開發小組。由於缺少人力來創建整個.NET替代產品，他們在2001年7月19日的歐萊禮大會創建了Mono的開源項目。

差不多三年後，Mono於2004年7月30日發布了1.0版本。Mono逐步從一開始的重點為Linux桌面應用程式開發者平台，到支援寛廣範圍的架構和作業系統，包含了嵌入式系統。

在2011年4月，Attachmate收購Novell後，針對Novell發布了上百位人力的解僱。在3月16號德伊卡薩在他的blog發佈在被Novell解僱後，他找到一家公司將透過Xamarin繼續支援Mono。原本的Mono團隊也被移到新的公司。Xamarin計畫維持在Mono的工作。由於在這時間點Novell仍然擁有MonoTouch和專為Android的Mono，所以計畫針對iOS和Android上重寫商業化的.NETstacks。

在這發表之後，這個專案的未來被質疑。因為，專屬 Android的MonoTouch and Mono變成跟現存Attachmate所屬的商業化商品有直接競爭，也考量了Xamarin團隊為了相同的作品而不使用之前在Novell開發的技術，證實是有困難的。無論如何，在2011年七月Novell、Attachmate的子公司及Xamarin發表了對Xamarin for Mono, MonoTouch and Mono for Android的永久性許可證，正式地帶起這個案子的管理方式。

發行日（Date）｜版本（Version）｜備註（Notes）

2004-06-30｜1.0｜C# 1.0 support

2004-09-21｜1.1

2006-11-09｜1.2｜C# 2.0 support

2008-10-06｜2.0｜Mono's APIs are now in par with .NET 2.0. Introduces the C# 3.0 and Visual Basic 8 compilers. New Mono-specific APIs: MonoCecil, MonoCairo and MonoPosix. Gtk# 2.12 is released. The Gendarme verification tool and Mono Linker are introduced.

2009-01-13｜2.2｜Mono switches its JIT engine to a new internal representation that gives it a performance boost and introduces SIMD support in the MonoSimd MonoSimd namespace. Mono introduces Full Ahead of Time compilation that allows developers to create full static applications and debuts the C# Compiler as a Service and the C# Interactive Shell （C# REPL）

2009-03-30｜2.4｜This release mostly polishes all the features that shipped in 2.2 and became the foundation for the Long-Term support of Mono in SUSE Linux.

2009-12-15｜2.6｜The Mono runtime is now able to use LLVM as a code generation backend and this release introduces Mono co-routines, the Mono Soft Debugger and the CoreCLR security system required for Moonlight and other Web-based plugins. On the class library System.IO.Packaging, WCF client, WCF server, LINQ to SQL debut. The Interactive shell supports auto-completion and the LINQ to SQL supports multiple database backends. The xbuild build system is introduced.

2010-09-22｜2.8｜Defaults to .NET 4.0 profile, C# 4.0 support, new generational garbage collector, includes Parallel Extensions, WCF Routing, CodeContracts, ASP.NET 4.0, drops the 1.0 profile support; the LLVM engine tuned to support 99.9% of all generated code, runtime selectable llvm and gc; incorporates Dynamic Language Runtime, Managed Extensibility Framework, ASP.NET MVC2, OData Client open source code from Microsoft;. Will become release 3.0

2011-02-15｜2.10

2012-10-18｜3.0｜C# 5.0 support, async support, Async Base Class Library Upgrade and MVC4 - Partial, no async features support.

2013-07-24｜3.2

2014-05-31｜3.4

2014-05-31｜3.6

2014-09-04｜3.8

2014-10-04｜3.10

## 目前的狀況與藍圖

截止2024年12月，Mono更新到了6.12.0.206版本，但項目已經由被微軟收購的Xamarin移交給WineHQ，官方建議將現有Mono應用程式遷移到同樣開源的.Net平台上。

## Mono組成元件

Mono組成元件包含了以下三類：

- 核心元件
- Mono/Linux/GNOME開發堆疊
- 微軟相容堆疊

核心元件包含了C# 編譯器，Common Language Infrastructure虛擬機器，以及核心類別程式庫。這些元件都是基於Ecma-334 and Ecma-335標準,而使得Mono能夠提供與標準相容、免費、並且是開放原始碼的CLI 虛擬機器。微軟曾經聲明這些標準都是基於Community Promise license的社群保護承諾之下。

Mono/Linux/GNOME開發堆疊則是提供了工具以用於開發應用軟體。這些工具使用了既有的GNOME以及自由並且開放原始碼程式庫，它們包含了針對圖形使用者介面（GUI）開發的Gtk#、可套用Gecko rendering engine的Mozilla程式庫、Unix整合程式庫（Mono.Posix）、安全性推疊、以及XML schema語言RelaxNG。Gtk# 讓Mono應用程式融入Gnome桌面環境而成為原生程式。資料庫程式庫則提供了與物件關連式資料庫連結的能力，這些資料庫包含了 db4o、Firebird、Microsoft SQL Server（MSSQL）、MySQL、Open Database Connectivity（ODBC）、Oracle、PostgreSQL、SQLite等等。在網站上可看見Mono專案一直都在持續更新維護資料庫程式庫。

微軟相容堆疊則是提供了一種方式來使得Windows .NET應用程式可以被移植到GNU/Linux上。這個堆疊包含了ADO.NET、ASP.NET以及Windows Forms等等。不過，由於這些元件並沒有被上述所說Ecma標準所涵蓋，因此部份元件有所謂專利恐懼與疑慮的問題。

## 架構

### 程式執行引擎

Mono程式的執行包含一個程式碼運作引擎，它會將ECMA CIL的byte code轉譯為原生碼（Native Code），它支援了以下處理器：ARM、MIPS（只有32位元模式）、SPARC、PowerPC、S390（64位元模式）、x86、x86-64以及IA-64 64位元模式。

程式的轉譯有三種模式：

- Just-in-time (JIT)編譯：在程式執行當中將ECMA CIL的byte code轉譯為原生碼。
- Ahead-of-Time (AOT)編譯：ECMA CIL的byte code（通常在.exe檔或.dll檔中）會轉譯出原生碼並儲存在作業系統中、以及CPU架構設定檔（例如在Linux上，如果是foo.exe，就會產生foo.exe.so檔）。通常，此種模式可產生出絕大部份前種模式所產生的原生碼，部份的例外是trampolines或是控管監督相關的碼（仍舊需要JIT來執行），由此可知AOT影像檔並非可以完全獨立執行的。
- 完全靜態編譯：這個模式只支援少數平台，它基於AOT編譯模式上，更進一步產生所有的trampoline、wrappers以及proxies，這幾樣東西是用於靜態連結出靜態檔案時所需。完全靜態編譯模式可以讓程式的執行期完全不需要用到JIT，這個做法適用於Apple iOS作業系統、Sony PlayStation 3以及微軟的XBox 360等作業系統。

從2.6版起，Mono開始支援使用LLVM來產生執行碼，而非原本自帶的方式。這對於高效能計算方面非常有用，因為在這種場合下，程式的執行效能比啟動速度來得重要。

從2.7 Preview版開始，使用者不再需要在程式編譯前的Configuration時就必須選定執行碼產生引擎，執行碼的產生可以在程式啟動時以`--llvm`或`--nollvm`的參數來指定即可，預設是以自帶的引擎為主，因為它的產生速度比較快。

### 垃圾回收

當2.8版推出時，Mono runtime提供了兩套垃圾回收器：generational collector以及Boehm conservative collector。在Mono 3.1.1版之前，預設的垃圾回收器（Boehm-Demers-Weiser Conservative Garbage Collector），跟商業環境如Java Virtual Machine或.NET framework的垃圾回收器相比，一直有很大的限制，在某些狀況的應用軟體上會發生記憶體洩漏的現象，這使得Mono無法用於需要長時間執行的伺服器應用。

一個稱之為「Simple Generational GC」（SGen-GC）的新一代垃圾回收器開始用於Mono中，在3.1.1版之後就直接變成是預設的垃圾回收器。對於Mono 2.8到3.1.0，使用者可以以傳入參數`--gc=sgen`來讓Mono runtime啟動時使用SGen垃圾回收器。這個新的垃圾回收器相較於傳統基於保守型掃描方式的回收器，有很多優點，它使用了generational garbage collection，從物件一開始被配置、到各個週期，所有活著的物件都會被轉移到較早代的記憶體池，這個想法是來自於因為許多物件都只是短暫使用的，因此可以被快速回收再利用，只有少數物件是長期性的存活在應用程式的整個生命期中。另外，為了改善效率，這個回收器對每個執行緒配置了個別的記憶體池，讓執行緒不需要跟別的執行緒打交道就可以自行配置記憶體區塊。對於前述所說，物件的轉移到較早代記憶體池的做法則是，在轉移之後，將所有目前指向該物件的指標都更新為新的位址。由於這樣的做法在大型物件時比較浪費記憶體，因此SGen為大型物件使用了獨自的記憶體池（Large Object Section），並且對這些物件使用mark-and-sweep演演算法。

目前SGen是以比較保守的方式來對待堆疊與暫存器，並且，那些可被參考到的物件是由它們的root來負責pin的動作。未來版本的Mono將會以精確方式來掃描託管的堆疊，藉此減少那些被pin的物件。

### 類別庫

類別庫為應用程式開發提供一套廣泛而有效的工具類。這些工具類可以用於任何.NET語言。類別庫被按命名空間進行了結構化，並被放置於稱為程序集的共享庫中。在我們談到.NET Framework時，我們多數是指這個類庫。

#### 命名空間和程序集

命名空間是一種用於將邏輯上相似的類按層次結構分組的機制。這種機制防止了命名衝突。在這種結構化採用被點號"."分隔的單詞來實現。通常最頂層的命名空間是System，例如System.IO和System.Net（完整的命名空間列表可以在Mono文檔中找到）。當然還有別的頂層命名空間，例如Accessibility和Windows就是這樣的例子。新建的命名空間還可以以開發組織的名字開頭。

程序集是這些類庫的物理載體。它們跟Win32共享庫一樣都是dll文件，儘管不完全一樣。一些程序集的例子有：mscorlib.dll，System.dll，System.Data.dll和Accessibility.dll。命名空間經常被分拆到幾個程序集中，而一個程序集可以由幾個文件組成。

### 公共語言基礎和公共語言規範

公共語言基礎（Common Language Infrastructure，CLI）是一套標準（ECMA335），公共語言運行時（Common Language Runtime）即CLR是CLI標準的實現，Mono是實現者之一。該運行時用於執行已編譯的.NET應用程式。公共語言基礎已被ECMA定義為標準ECMA-335。要運行一個.NET應用程式，你必須使用相應的參數調用運行時。

在ECMA-335的第六章詳細說明了「公共語言規範」（Common Language Specification，CLS）並定義了提供給公共語言基礎的接口，例如對於枚舉類型的隱含表示類型的協定。Mono的編譯器負責生成符合公共語言規範的映射代碼，即公共中間語言（Common Intermediate Language，CIL）。Mono的運行時將運行這類代碼。ECMA標準先前還定義了一個符合公共語言規範的程序庫作為應用框架。

### 託管與非託管代碼

在原生的.NET/Mono應用程式中，所有代碼都是託管的，也就是說，是受管於CLI式的記憶體管理和線程安全管理的。其它的.NET或Mono應用程式可以通過使用System.InterOpServices庫創建C#綁定來調用已存的非託管代碼。很多移植到Mono的類庫使用了CLI的這個特性，例如Gtk#。

### 相關項目

現有大量與Mono相關的用於擴展Mono的項目，這些項目允許開發者在他們的開發環境中使用Mono。這些項目包括：

- Cocoa#，對原生Mac OS X工具包的一系列包裝（Cocoa）。
- Gecko#，一個對在Mozilla中使用的嵌入式布局引擎的綁定（Gecko）。
- Gtk#，對使用C的GTK+庫的C#的外包。
- Tao，一個圖形及遊戲庫的綁定。

## 授權

Mono是透過Xamarin的雙重授權，相似於其他產品，如Qt和Mozilla application Suite。Mono's C#編譯器與工具是依照GNU Leasser General Public License（LGPLv2 only）來釋出（開始於Mono 2.0，Mono C#的編譯器源碼在MIT X11 License仍然是有效的），屬於GNU Leasser General Public License（LGPLv2 only）的runtime函式庫及屬於MIT X11 License的類別函式庫。

有完全免費的軟體與開源授權，因此Mono是免費的開源軟體。

C#編譯器的授權改變是從GPL到MIT X11授權，允許編譯器的程式碼在少許的GPL限制例子中被重複使用，如例：

- 作為服務的Mono編譯器

```
 * Mono互動介面的Shell
 * Mono可崁入的的C#編譯器
```

- Mono的C# 4.0的動態綁定的實作
- MonoDevelop的內建parser和AST圖

## Mono與微軟的專利

人們對於微軟能否採用專利摧毀Mono項目進行了大量的爭論。其實，專利問題不在於已被提交到ECMA組織的核心技術或Unix/Gnome的專有部分，而在於由微軟基於.NET Framework創建的技術，例如ASP.NET、ADO.NET和Windows Forms。這些技術在Mono中至今還沒有被完全地實現，事實上，在開發Mono應用程式時也不需要用到，然而，在開發基於Windows平台的程序時卻是不可缺少的。Mono團隊將目標定為將這些技術納入到項目中，並制訂了一個三步驟策略來處理它們：

- 採用其它實現方式來實現從而繞過專利問題
- 把包含專利的代碼清除出項目
- 找出「現有技術（prior art）」從而將專利變為非專利

顯然，第一個選項並不總是可行的。對於一些問題，例如那些與協同工作和交互相關的，可能就只有一種解決方案。由於這個相同的原因，儘管第二個選項總是可行的，它卻可能導致一個開發出來的產品並不能作為.NET的替代品。第三個選項則是昂貴的，甚至不可能的，這需要一定程度的運氣。

## 使用Mono開發的軟體

以下是使用Mono API和C#編寫的部分程序：

- Banshee是一個用於GNOME的音樂管理和播放軟體。
- Beagle是一個桌面搜索軟體。
- Blam!是一個RSS 新聞聚集器，特別適合於閱讀如Planet Gnome這樣的行星資訊。
- Bless是一個十六進位編輯器。
- CDCollect是一個CD 編目應用程式。
- Diva是一個用於GNOME的影片編輯器。
- F-Spot是有個由Novell開發的圖片便捷管理程序。
- Fiddler是一個強大的Web 抓包工具，與Charles齊名。
- Galaxium是一個MSN 即時通訊軟體客戶端。
- GLyrics是一個歌詞搜索器。
- Gpremacy是以Mono/Gtk# 實作的圖版遊戲Supremacy
- iFolder 3（by Novell）讓你使用點對點協議（peer-to-peer）或Novell的群集伺服器產品與其它電腦和使用者共享文件。
- imeem一個社交網路軟體。Mac版本的使用者端和伺服器使用Mono運行，而Windows版本的使用者端仰賴於Microsoft.Net
- KeePass是一款開源的密碼管理器。
- MindFire是一個用於輔助速讀（speed reading）的跨平台電子書閱讀器
- MonoDevelop是一個用於創建Mono應用程式的集成開發環境。該軟體原先是SharpDevelop向Gtk#的一個移植，而現今該軟體已獨立開發。該軟體在Windows上有測試版的可用版本。
- Pinta是一個簡單的位圖形編輯軟體。

## 分支版本

2011年4月，Novell公司被Attachmate公司所併購，而原先在Novell公司裡的Mono開發者被大量資遣。2011年5月，原先Mono的開發者另外成立一家Xamarin的公司，仿Mono發行他們的Xamarin跨平台.NET套件，在Windows下能與整合到Microsoft Visual Studio的IDE之中。2011年7月，Attachmate公司旗下的Novell公司批准了Mono相關專案到Xamarin的授權。

## 備註

- licenseFor more information about the licensing, see Mono FAQ: Licensing

## 參考文獻

- This article incorporates text from Mono's homepage，which is in the GNU Free Documentation License.

## 外部連結

- GotMono?, Mono community homepage
- Mono Forum
- Mono Live，LiveCD website
- Running .NET on Linux or Windows
- Ximian Forum
- Slashdot: Fedora Core 5 includes Mono
- Novell, Inc.

國際站點

- Mono France，A French Mono WebSite
- MonoBrasil，A Brazilian Mono WebSite
- MonoColombia，A Colombian Mono WebSite
- MonoGermany，A German Mono WebSite
- MonoHispano，A Spanish Mono community
- Japanese Mono Mono web site translation to Japanese.
- MonoPoland，Polish Mono Web site.
- Mono Netherlands，Dutch Mono site.

## 基本資料

- 開發者：Novell, Xamarin
- 軟體版本週期：6.12.0.122
- 作業系統：跨平台
- 類型：系統平台
- 許可協議：GPL、LGPL與MIT許可證，或雙重許可
- 網站： http://www.mono-project.com/