2008年6月27日星期五

浅谈Gecko关键部分之三线程管理及主要线程

作为一个浏览器内核,Gecko所要完成的任务是非常繁杂的,其主要任务就是根据用户提供的资源地址,通过http协议从Web服务器中取得页面文档,然后解析其内容,最后根据一定的约定在浏览器指定区域中显示出页面,其中往往涉及网络编程及图形界面编程,而大家通常都知道的是网络编程中的连接、读取数据等往往需要考虑到服务器端的情况,一般采用异步方式来确保有效处理服务端返回的数据包括连接不成功、错误处理等;而图形界面的处理往往需要采用一个主消息循环及回调函数的方式来处理用户的动作,为了给用户提供平滑的操作及兼顾后台服务器的不确定性,一个可行的浏览器内核必须充分利用多线程来协调处理复杂的应用场景,只有这样才能高效的完成其所要完成的任务,如果能够初步了解Gecko内核的线程模型及相关线程管理的知识,对了解Gecko是非常有帮助的,下面初步了解Gecko是如何进行线程管理及其主要线程实现。

一、Gecko线程模型
为了统一接口编程,Gecko将其线程模型按照组件的方式来处理,定义的接口主要有nsIRunnable、nsIEventTarget、nsIThread、nsIThreadManager、nsIThreadPool,其中nsIThreadManager由nsThreadManager来实现,它主要用于来管理所有的nsThread,包括创建nsThread实例,并通过维护一些系统原生线程的属性可以判断同一段代码是在什么线程的上下文中调用,从而可作出不同的处理,如GetIsMainThread可以判定当前执行线程是否为主线程,这一点在Gecko中应该得到了充分的应用,同时nsThreadManager的实例属于sington模式,在第一次启用XPCOM组件时由NS_InitXPCOM3实例化出来,以供以后管理nsThread使用;

nsThread代表一个一般意义上的原生线程,在其构造函数中会初始化它并启动原生线程,它同时增加了EventQueue及ThreadObserver的概念,其函数入口为nsThread::ThreadFunc,在线程的整个周期中也即nsThread::ThreadFunc中不断的处理外部线程或本身向其EventQueue中Dispatch来的Event,同时每处理一个Event之前都会检查其是否存在Observer,如存在则先让Observer调用其OnProcessNextEvent来处理该Event,然后调用Event本身提供的run方法,这样增加了nsThread处理Event的灵活性;同时nsThread统一由nsThreadManager来创建,通过调用其Shutdown方法来结束该线程;并提供了一组外部接口来进行线程管理操作,如
NS_NewThread、NS_GetMainThread、NS_DispatchToMainThread、NS_ProcessNextEvent等以供不同线程调用,同时保证线程安全;

nsThreadPool代表一组线程,当外部向其Dispatch一个Event时它先会向其中的EventQueue添加该Event,然后它会根据设置的参数来决定是否分配一个nsThread来处理该Event,一旦创建了一些nsThread则将其维护在mThreads队列中,同时向该nsThread Dispatch这个nsThreadPool实例以让该nsThread去执行该nsThreadPool的run方法,这样可保证线程池中的每个nsThread的执行体都是nsThreadPool中的run方法,在其run方法中会根据是否空闲等条件自动ShutDown一些暂时不用的nsThread,以达到线程池的目的,即当任务事件Event繁多的时候多开启一些线程来处理,一旦任务完成则释放大部分空闲线程,保持一小部分线程以等待新任务的分配及提交;nsThreadPool在异步读取网络流数据的时候会经常用到,以后有机会可具体分析其应用场景;

二、Gecko主要线程
MainThread是Gecko的主线程,也即进程启动时的执行序列,它主要处理图形界面的消息循环以及其他线程向它Dispatch过来的Event,这样可以有机的结合图形界面的处理及网络数据的读取、解析、渲染等。MainThread线程充分利用了Gecko线程模型特点,既能处理原生的窗口消息,又可及时处理其它线程通知给它的Event,其执行主体往往是Gecko的核心,据初步统计其执行时间往往占整个程序执行时间的90%以上,其效率的高低直接决定了是否会让用户产生阻塞停顿的感觉。其主要实现逻辑是在启动XPCOM当中会在nsThreadManager初始化时自动产生一个nsThread实例mMainThread,它代表进程启动时的执行序列,待该执行序列完成其他基本准备后,在nsBaseAppShell::Init中将其Observer设置为nsBaseAppShell实例本身,具体参考如下:

nsresult nsBaseAppShell::Init()
{ // Configure ourselves as an observer for the current thread:
nsCOMPtr threadInt = do_QueryInterface(NS_GetCurrentThread()); NS_ENSURE_STATE(threadInt);
threadInt->SetObserver(this);//mObserver=>this
nsCOMPtr obsSvc = do_GetService("@mozilla.org/observer-service;1");
if (obsSvc) obsSvc->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
return NS_OK;
}

NS_IMETHODIMP nsBaseAppShell::Run(void)
{
nsIThread *thread = NS_GetCurrentThread();
NS_ENSURE_STATE(!mRunWasCalled); // should not call Run twice mRunWasCalled = PR_TRUE;
while (!mExiting) NS_ProcessNextEvent(thread);
NS_ProcessPendingEvents(thread);
return NS_OK;
}

PRBool NS_ProcessNextEvent(nsIThread *thread, PRBool mayWait)
{
nsCOMPtr current;
if (!thread) {
NS_GetCurrentThread(getter_AddRefs(current));
NS_ENSURE_TRUE(current, PR_FALSE);
thread = current.get();
}
PRBool val;
return NS_SUCCEEDED(thread->ProcessNextEvent(mayWait, &val)) && val;
}

NS_IMETHODIMP nsThread::ProcessNextEvent(PRBool mayWait, PRBool *result)
{
..........
nsCOMPtr obs = mObserver;
if (obs) obs->OnProcessNextEvent(this, mayWait && !ShuttingDown(), mRunningEvent);

mEvents->GetEvent(mayWait && !ShuttingDown(), getter_AddRefs(event));
*result = (event.get() != nsnull);
nsresult rv = NS_OK;
if (event) {
++mRunningEvent;
event->Run();
--mRunningEvent;
}
else if (mayWait)
{ .........}

if (obs) obs->AfterProcessNextEvent(this, mRunningEvent);
..........
return rv;
}

其中关键点在于MainThread的mObserver是nsAppShell实例,那么它的OnProcessNextEvent都作了些啥呢?主要是根据情形调用其ProcessNextNativeEvent方法,其实现如下:

PRBool nsAppShell::ProcessNextNativeEvent(PRBool mayWait)
{
PRBool gotMessage = PR_FALSE;
do
{
MSG msg; // Give priority to system messages (in particular keyboard, mouse, timer, // and paint messages).
if (PeekKeyAndIMEMessage(&msg, NULL) ::PeekMessageW(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) ::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
gotMessage = PR_TRUE;
if (msg.message == WM_QUIT)
{
Exit();
}
else {
::TranslateMessage(&msg);
::DispatchMessageW(&msg);
}
}
else if (mayWait) {
// Block and wait for any posted application message
::WaitMessage();
}
} while (!gotMessage && mayWait);
return gotMessage;
}
这个函数是否觉得非常的面熟???

nsSocketTransportService作为异步处理socket读写的线程,在程序启动就会实例化,有时间可以仔细看看\mozilla\network\base\src\nsSocketTransportService2.cpp,其主要代码应该与一般多线程网络程序差不多。

至于其他关于TimerThread、ThreadPool及javascript垃圾回收线程等以后有时间再来分析。

三、参考网址
The Thread Manager
XPCOM:nsIThreadManager

2008年6月20日星期五

浅谈Gecko关键部分之二内存分配使用回收

2008年6月17日Firefox3Release版本已正式发布啦,可喜可贺,毕竟经历3年多的努力Mozilla社区终于又能给大家带来一些震撼、新希望,甚至冲动,其中包含很多人性化的东东以及最近几年发展起来的很多有趣的extensions,并且经过一些比较,似乎这个版本部分解决了困扰人们很久的内存使用大多及内存泄漏的问题,是否完全能化解人们心中的疑问可能还有待时间及实践来证明。借助人们很关注的问题,今天也来了解了解相关的内存分配使用回收问题。内存的使用及防止泄漏是c/c++程序员非常关心的问题,一旦有泄漏发生往往都感觉到非常头痛,所以我们也很有必要关心这方面的问题,看看Firefox这些Hacker们究竟是如何来面对这些问题的。

一、内存管理的主要方式
为了尽可能合理高效的使用内存,不同的系统使用了一些各具特色的内存管理机制,1、以java为代表的garbagecollector,所有的资源经由虚拟机来分配、回收,大大降低了java程序员对内存管理的困扰,但也带来了程序速度启动变慢,占用内存较多的问题,特别在程序使用了多种资源后,当然这种机制还在脚本语言如javascript、python、perl等的实现中也得到充分的使用,并且通过一些优化算法,已经达到了很好的效果;2、以linux内核为代表Slab allocation机制,它通过一些缓存及固定长度分配器来有效解决由于多次及不固定长度内存分配可能带来的内存碎片问题;3、以apache为代表的内存池机制,它往往会先malloc一大块内存,以供后续程序内存申请使用,特别在内存分配申请频繁的情况下大大降低程序对系统层的内存申请次数,同时可以起到类似部分garbagecollector的作用。

二、主要Gecko内存管理机制
1、组件的生命周期可简单归纳为首先在factory的createInstance中通过new出一个类实例,然后通过queryInterface进行接口转换及维护mRefCnt,并检查mRefCnt是否为0,如是则delete该实例,主要实现原理可参考XPCOM组件相关开发资料,对应源代码可参考\mozilla\xpcom\glue\nsISupportsImpl.h及\mozilla\xpcom\glue\nsISupportsUtils.h等。当然也有部分类override operator new方法,但往往都是作清零的处理,根本没涉及到更深层的内存管理,而new/delete动作往往分别直接对应系统层的malloc/free方法,所以几乎没有上面提到的垃圾回收、Slab及内存池的使用,当然对javascript的实现是肯定会有相关垃圾回收机制的,但它的出发点往往为了满足脚本语言的要求。

2、对于一些字符串及数组的内存使用往往采用NS_Alloc/NS_Free等,其实现代码对应于XPCom的FrozenFunctions中指定的AllocFunc/FreeFunc,其由\mozilla\nsprpub\pr\src\malloc\Prmem.c中对应的PR_Malloc及PR_Free来实现,其中根据是否使用use_zone_allocator来检查直接调用系统malloc及free还是采取一定类似内存池及slab allocation的方法来统一管理内存的分配。其具体实现代码可详见\mozilla\nsprpub\pr\src\malloc\Prmem.c及Prmalloc.c等。对于NS_Alloc/NS_Free的使用,往往用在一些atoms、tags等当中,总的说来使用不是很多。。

3、为了防止组件之间的循环引用,引入了nsICycleCollector来单独处理这个问题,以尽可能的避免无法释放由于程序逻辑造成的内存冗余,具体实现可参考\mozilla\xpcom\base\nsCycleCollector.cpp;同时为了让程序占系统内存达到一定比例后,采用momory reporter机制要求系统flush/swap一些内存,供程序继续使用;另外结合nsGarbageCollector及nsLeakDetector来扫描stack检测是否存在内存泄漏。

4、网上关于gecko的内存使用的讨论非常多,现提供一些相关资料以供大家参考,从多方面了解gecko内存管理等方面的问题,从自己的角度来了解它,以拓展我们的思路。

2008年6月13日星期五

浅谈Gecko关键部分之一XPCOM组件

为了便于统一认识下面将Gecko统称为Firefox内核引擎而不仅仅代表渲染引擎,为了能更加有效的加深对它的理解,能够从本质上了解它的构成,下面从个人认为最为关键的几个部分来分析了解它,争取通过对这几个关键部分的了解总结能让自己从六百万行Gecko代码中逃脱出来,进而产生一点点一览纵山小的感觉,以致对Gecko的认识有本质上的提升。现首先从XPCOM组件开始,因为它是Gecko的基础,就像COM对于windows,没有从根本上对XPCOM的理解与把握就不可能对Gecko有深入的理解,同时对XPCOM的理解也只是对Gecko理解的入门。

一、究竟什么是XPCOM?
XPCOM is a cross platform component object model. It has multiple language bindings, letting the XPCOM components be used and implemented in JavaScript, Java, and Python in addition to C++.它是一个组件对象模型,与Windows中的COM非常类似,如果以前深入接触过COM的朋友,应该对XPCOM的认识会很轻松,个人认为它相对COM来讲可能相对简单点,毕竟它不涉及到线程管理、内存管理,从大体来讲它仅仅包括最基本的对象生命周期管理模型,当中涉及到类工厂、Sington等模式的应用。可能由于XPCOM刚开始在90年代初设计的时候,对组件对象模型的认识还比较浅显,所以它采用了最基本的引用计数形式来管理组件对象,没有更深层次的与内存管理、线程管理结合起来,可能正是由于这个原因在Gecko的代码中经常看到相关的注释提醒作者注意这个变量是referenced,而不会真正的参与到真实对象的生命周期管理,以防止对象间循环引用,从而给可能的内存泄漏埋下了祸根。

二、为什么需要XPCOM?
也许这样问有人或许觉得很白痴。不过个人觉得如能真正理解为什么需要XPCOM,那么针对形式各异的XPCOM组件运用也就会见怪不怪啦。需要XPCOM这个模型个人认为应该是基于接口编程的真实需要,基于接口编程能够有效的实现对业务对象基于平台、基于语言及实现形式的扩展。Gecko作为一个跨平台的内核引擎,倘若没有这种基于接口的模型会使系统变得更加的庞杂,也许为了更加简单及统一Gecko已将XPCOM这一对象模型发挥引用得淋漓尽致,基本上能抽象独立出来的逻辑业务如Timer、Thread、EventQueue、http等等都通通定义成含有相对固定接口的对象模型。其实作为一个大型复杂系统,个人认为这样做是很有必要的。

现举两三例来说明,试想不同的平台如windows、linux等都有不同的图形界面接口,其中有的是原生的如xlib、windows原生接口,也有抽象层的如gtk、qt、wxwidget、mfc等,作为一个可以支持多种图形界面接口的内核,首先在结合自身需要及原生图形界面接口的基础之上抽象出诸如nsIBaseWindow、nsIWidget、nsIMenu、nsIEventSink等等公共的接口,然后针对不同平台的具体实现分布在mozilla\widget\src\不同的qt、windows、gtk2、mac目录中,这样直接明了统一。同时值得留意的是mozilla\widget\src\build\目录下有一个nsWinWidgetFactory.cpp,其主要职责在于根据编译选项选定的平台注册对应目录下实现的组件,以供其他组件调用。其主要内容为:
static const nsModuleComponentInfo components[] =
{
{ "nsWindow",
NS_WINDOW_CID,
"@mozilla.org/widgets/window/win;1",
nsWindowConstructor },
{ "Child nsWindow",
NS_CHILD_CID,
"@mozilla.org/widgets/child_window/win;1",
ChildWindowConstructor },
{ "Clipboard",
NS_CLIPBOARD_CID,
// "@mozilla.org/widget/clipboard/win;1",
"@mozilla.org/widget/clipboard;1",
nsClipboardConstructor },
{ "Clipboard Helper",
NS_CLIPBOARDHELPER_CID,
"@mozilla.org/widget/clipboardhelper;1",
nsClipboardHelperConstructor },
{ "AppShell",
NS_APPSHELL_CID,
"@mozilla.org/widget/appshell/win;1",
nsAppShellConstructor },
{ "Toolkit",
NS_TOOLKIT_CID,
"@mozilla.org/widget/toolkit/win;1",
nsToolkitConstructor },
{ "Look And Feel",
NS_LOOKANDFEEL_CID,
"@mozilla.org/widget/lookandfeel;1",
nsLookAndFeelConstructor },
{ "Transferable",
NS_TRANSFERABLE_CID,
// "@mozilla.org/widget/transferable/win;1",
"@mozilla.org/widget/transferable;1",
nsTransferableConstructor },
{ "HTML Format Converter",
NS_HTMLFORMATCONVERTER_CID,
"@mozilla.org/widget/htmlformatconverter;1",
nsHTMLFormatConverterConstructor },
};

NS_IMPL_NSGETMODULE(nsWidgetModule, components)

其实Gecko的实现代码中与此类似的有很多很多,如我们大家了解的MIMI类型有很多如html、xml、svg、txt、jpeg、gif、png等等,首先抽象出nsIDocument,然后依据其类型的不同分别实现其对应的逻辑,具体可参考\mozilla\content\base\public\nsIDocument.h;\mozilla\content\html\document\src\nsHTMLDocument.cpp,nsImageDocument.cpp;\mozilla\content\xul\document\src\nsXULDocument.cpp等;再如我们了解浏览器实现的协议有http、ftp等,为了统一不同协议的实现框架及能扩展到不同的协议,首先抽象出一组接口如nsIURL、nsIStreamListener、nsIStreamLoader、nsIChannel、nsIRequest、nsIRequesetObserver等,然后在不同的目录如http、ftp、file中按公共接口框架实现其逻辑,Gecko利用这种协议接口框架还扩展了about、data、resource等协议模式,如果了解了其公共接口框架并初步了解其中一个协议的实现方式,我们就可很方便的扩充到未实现的协议或自定义的协议实现。Gecko利用XPCOM模型为我们提供了很多很多类似的公共接口框架,以便扩展,其实总的说来,对于Gecko来讲这种方式几乎无处不在,正是这样的架构设计创造了Gecko的强大、丰富而具有生命力。有兴趣的朋友可以按这个基本思路从其代码实现中找到诸如扩展一个html标签、一个css属性、一种文件格式等等实现范例,以掌控其设计精髓以致扩展它为我们所用。

三、XPCOM主要特性
在XPCOM提供了丰富的功能的基础上,个人认为其主要特性有1、需要深入了解其引用计数对象管理机制及内存管理,特别在与跨语言方面如javascript、python等的实现与交互时,须防止跨边界的内存泄漏;2、很多组件通过xpconnect已实现与javascript的交互<其实这是Gecko非常重要的一部分,以后有机会再专题分析>,大大丰富了用c/c++实现的组件的应用场景,当然XPCOM组件也提供了与python、java方面的扩充与交互,不过支持程度没有javascript强,因为毕竟XPCOM组件与javascript的交互是Gecko的基石;3、为了充分利用组件对象模型,Gecko的实现中使用了大量的Sington、Observer、adapter等设计模式,如在nsDocShell中关于nsIWebProgress、AddProgressListener、nsIInterfaceRequestor等相关实现中得到充分的体现。其中Sington模式的使用有时往往具有鲜明的特点。其一般实现为XXXService,如WindowWatcher、CommandLineHandle、UriLoader等等。
///*****************************************************************************
// nsDocShell::nsIInterfaceRequestor
//*****************************************************************************
NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink)
{
NS_PRECONDITION(aSink, "null out param");

*aSink = nsnull;

if (aIID.Equals(NS_GET_IID(nsIURIContentListener))) {
*aSink = mContentListener;
}
else if (aIID.Equals(NS_GET_IID(nsIScriptGlobalObject)) &&
NS_SUCCEEDED(EnsureScriptEnvironment())) {
*aSink = mScriptGlobal;
}
else if ((aIID.Equals(NS_GET_IID(nsIDOMWindowInternal)) ||
aIID.Equals(NS_GET_IID(nsPIDOMWindow)) ||
aIID.Equals(NS_GET_IID(nsIDOMWindow))) &&
NS_SUCCEEDED(EnsureScriptEnvironment())) {
return mScriptGlobal->QueryInterface(aIID, aSink);
}
else if (aIID.Equals(NS_GET_IID(nsIDOMDocument)) &&
NS_SUCCEEDED(EnsureContentViewer())) {
mContentViewer->GetDOMDocument((nsIDOMDocument **) aSink);
return *aSink ? NS_OK : NS_NOINTERFACE;
}
else if (aIID.Equals(NS_GET_IID(nsIPrompt)) &&
NS_SUCCEEDED(EnsureScriptEnvironment())) {
nsresult rv;
nsCOMPtr wwatch =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr window(do_QueryInterface(mScriptGlobal));

// Get the an auth prompter for our window so that the parenting
// of the dialogs works as it should when using tabs.

nsIPrompt *prompt;
rv = wwatch->GetNewPrompter(window, &prompt);
NS_ENSURE_SUCCESS(rv, rv);

*aSink = prompt;
return NS_OK;
}
else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
return NS_SUCCEEDED(
GetAuthPrompt(PROMPT_NORMAL, (nsIAuthPrompt **) aSink)) ?
NS_OK : NS_NOINTERFACE;

}
else if (aIID.Equals(NS_GET_IID(nsISHistory))) {
nsCOMPtr shistory;
nsresult
rv =
GetSessionHistory(getter_AddRefs(shistory));
if (NS_SUCCEEDED(rv) && shistory) {
*aSink = shistory;
NS_ADDREF((nsISupports *) * aSink);
return NS_OK;
}
return NS_NOINTERFACE;
}
else if (aIID.Equals(NS_GET_IID(nsIWebBrowserFind))) {
nsresult rv = EnsureFind();
if (NS_FAILED(rv)) return rv;

*aSink = mFind;
NS_ADDREF((nsISupports*)*aSink);
return NS_OK;
}
else if (aIID.Equals(NS_GET_IID(nsIEditingSession)) && NS_SUCCEEDED(EnsureEditorData())) {
nsCOMPtr editingSession;
mEditorData->GetEditingSession(getter_AddRefs(editingSession));
if (editingSession)
{
*aSink = editingSession;
NS_ADDREF((nsISupports *)*aSink);
return NS_OK;
}

return NS_NOINTERFACE;
}
else if (aIID.Equals(NS_GET_IID(nsIClipboardDragDropHookList))
&& NS_SUCCEEDED(EnsureTransferableHookData())) {
*aSink = mTransferableHookData;
NS_ADDREF((nsISupports *)*aSink);
return NS_OK;
}
else if (aIID.Equals(NS_GET_IID(nsISelectionDisplay))) {
nsCOMPtr shell;
nsresult rv = GetPresShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell)
return shell->QueryInterface(aIID,aSink);
}
else if (aIID.Equals(NS_GET_IID(nsIDocShellTreeOwner))) {
nsCOMPtr treeOwner;
nsresult rv = GetTreeOwner(getter_AddRefs(treeOwner));
if (NS_SUCCEEDED(rv) && treeOwner)
return treeOwner->QueryInterface(aIID, aSink);
}
else {
return nsDocLoader::GetInterface(aIID, aSink);
}

NS_IF_ADDREF(((nsISupports *) * aSink));
return *aSink ? NS_OK : NS_NOINTERFACE;
}

四、XPCOM相关参考资源

2008年6月7日星期六

认识了解Mozilla,Gecko,FireFox

最近关于浏览器的新闻很多如Firefox3RC2已经发布了,过不了多久许多Fans翘首以盼很久的Firefox3正式版本也就粉墨登场啦;IE8、Safari、Opera都正热火朝天的发Beta版,似乎真有浏览器大战的架式;这不国内的Maxthon也想更换或调整其浏览器内核,看样子浏览器开发可正引领目前IT技术发展的一个潮流,再加上所谓AIR平台的发展,简直赚足了人们的眼球,大有当年Java刚出现时所展现的风光及所向披靡。

哪其中究竟有什么值得我们这些具有贫瘠IT技术引领创新能力的阿斗所特别需要关注的呢?
首先作为一个IT技术应用成员,觉得大家应该好好重视这个现象包括浏览器开发、web2.0、手机开发等,因为它或许会决定你我今后5年或10年的IT技术及应用发展方向,直接决定我们的生存方式及能否生存。其中原因应该在于Web的发展日益与人们的生活分不开,它需要更新,需要发展<可以自己从最基本的想想看>。

其次这次所谓的浏览器大战的始作俑者应该是Mozilla,这个基金会与浏览器的出现及Web的发展有作千丝万缕的关系(大家有兴趣可以搜索一下浏览器的发展就知道啦),并且Mozilla开发所涉及的方面也是最为全面的如浏览器、AIR、手机等方面,而Mozilla的重中之重应该就是Gecko内核,所以我们很有必要深入了解认识一下它们Mozilla、Gecko及Firefox,包括它们的过去、现在及将来。

下面初步的认识了解一下它们
一、Mozilla严格说应该是一个开源基金会,不是一家公司,它应该具备世界上开源组织所特有一些特性如非盈利为目的、开源,有一群狂热的IT牛人在捣鼓着,不过目前它应该得到谷歌的大力支持,也许谷歌自己不单独开发浏览器也就是因为Mozilla。有空可去其官方网站
http://www.mozilla.org/foundation/瞧瞧。。。

二、Gecko应该说是 a layout engine originally created by Netscape Communications Corporation for the Mozilla application suite and now used in all applications developed by Mozilla, including later Netscape Navigator releases.它包含浏览器及AIR平台的核心,其主要实现支持标准有
应该说要了解Firefox必须了解Gecko,目前版本为1.9a,是除IE内核Trident之外第二大浏览器内核,同时它具有独到的特点:跨平台,支持windows、类unix、Mac;对XUL的充分实现与支持,仅这一点就超越了以往界面实现方式,并且经过多年的测试及提升应该有了很好的执行效率,其实这也是AIR所创导的核心;当然它也支持SVG、RDF、XBL;还有更重要的是它是定义及实现javascript的鼻祖,并正引领着javascript虚拟机化(大家想想看java的虚拟机的威力),一旦整合了jvm实现技术中的优缺点,其威力可真不少,再说jvm已经发展10多年啦,相关技术已稳定成熟,那些IT大牛们完全可以采取拿来主义,很有可能比jvm实现得还要好,这样的话也许以后一般的电脑完全真的只需要一个浏览器就可以搞定一切啦。Gecko中的两大主题content/layout/render、javascript发展的好坏直接决定其能否在浏览器大战中胜出,当然其他的浏览器或平台要想在浏览器大战中突出重围必须在这两者之间杀出一条血路,目前综合说来Gecko占有一定先发优势,同时是其他竞争者模仿、想超越的对象,所以对于我们来讲具有很大的参考学习作用,同时毕竟是开源的嘛。

三、Firefox 应该说仅仅是一个浏览器而已,它能够象IE一样满足大家上网冲浪的切实需求,同时它或许更安全更小巧;但由于它完全基于Gecko内核便于扩充,这不http://addons.mozilla.org/?application=firefox上就有各种各样好玩的东东等着大家去捣捣,也许会让你发出原来自己的浏览器竟然可以变成这样的感叹,这不Web应用开发两大巨头谷歌、雅虎公司已经在其中开发了不少应用,很值得看一看借鉴借鉴。或许正是这么多因素导致Firefox正引领着浏览器的使用及发展,毕竟使用浏览器上网的人非常非常多,具有个性化的上网活动也许正在形成,应该说Firefox正深深的紧密的参与其中。

其实国内听说了解Firefox也许不少,但经常使用Firefox的人相对来说还是蛮少的,真正了解Mozilla及Gecko的人也许就更少啦,但个人觉得Firefox、Gecko这两年发展可真快了,或许它就是未来的发展方向,抛点砖希望大家有空一起了解关注甚至研究研究Firefox/Gecko。

参考网址

2008年6月1日星期日

新的启航,简单快乐的活着!

今天第一次开始写点东西,希望能给平平庸庸的生活添点色彩、动力、希望。

今天同时也是儿童节,祝一些过成年人儿童节的朋友们节日快乐开心。虽然童年时代已经较远,蓦然回首,是否觉得岁月无情,蹉跎岁月犹如滚滚长江东去水;是否觉得我们的天空与童年时代的有太多的不同;是否觉得我们已不再年轻,不再有理想,不再简单而快乐着;是的,我们长大了,生活环境变了,欲望多了,压力大了,苦恼多了,变得不再那么的简单。

过去的就让它过去好啦,我们目前的生活还要继续,但愿能多点童心去发现认识这个世界,多带来一点点快乐,有空可与小朋友一起玩玩,想他所想,按他们喜欢的方式去生活,这不从电视上看到四川灾区的小朋友与外国大朋友一起玩耍是多么的开心与快乐?!也许世界本来就很简单,我们得坚强简单开心的活着。。。

作为技术从业人员,每天与似乎冷酷无情的什么语言、工具、Bug打交道,再好的童心也给泯灭啦!这不恕我建议大家把我们学习的语言、工具权且当作我们小时候玩的玩具好啦,找自己喜欢的,有时间就与小朋友一起去切磋,玩的不开心了,换个玩具,换些朋友一起玩;如果有捣鼓拆玩具的冲动,可别忘了带着小时的童心去捣鼓,过不多久,说不定您就变成了胜利大王,天下无敌呢。。。

好了,但愿大家面对枯燥的生活,多去捣鼓捣鼓,简单快乐至上。不过有点需要提醒自己的就是童年时代爱好学习或玩的习惯可千万不要丢了(这不有科学家研究发现3岁前我们的思维方式性格等就已基本成型,会无形中影响我们一生呢?何不充分调动起小时就养成的方法方式来面对现在的一切呢?!),长大了我们必须到社会上去学习去玩,学的越快玩的越开还是一样的很值得骄傲开心哦!如果还能保持点童心,那可就锦上添花啦,说不定您就能变成故事小说中的老顽童呢。

让我们一起简单快乐的活着,人生苦短,从童年到成年,您感受到了吗?!