??xml version="1.0" encoding="utf-8" standalone="yes"?>
Python, EiffelQC#QRoby{无一例外地都使用了GC机制。但既然Java中的GC最名,所以天?br />
下来自然应该抗着?/span>
q篇短文源于comp.lang.java.programmer跟comp.lang.c++上发生的一场大辩论Q支持C++和Java
的两z不同势力展开了新世纪W一场冲H,跟脓(chung)发言过350Q两zN有名角压cC++阵营的擂L
Pete BeckerQACM会员QDinkumware Ltd. 的技术副ȝ。此君精通C++和JavaQ开发过两种语言?br />
核心cdQ但是却对C++狂热之极Q而对于Java颇不以ؓ然。^时谈到Java的时候还好,一旦有
敢用Java来批判C++Q立d不住火爆脾气跛_出来Q以坚韧不拔的毅力和大无畏精与Ҏ(gu)周旋Q?br />
舌战儒Q哪怕只剩下一个h也要血战到底。这{奇人当真少见!我真奇怪他整天泡在usenet上,
不用工作么?他的老板P.J. Plauger如此宽宏大量QJava阵营主角是一个网名Razzi的兄弟,另外?br />
Sun公司大名鼎鼎的Peter van der Linden助阵Q妙语连珠,寸土必争Q加上h多势众,一度占据优ѝ?br />
C++阵营里大拿虽然很多,但是大多数没有Pete那么多闲工夫Q例如Greg ComeauQComeau公司老板Q?br />
每次来个只言片语Q实在帮不了Pete多大忙。但是自从C++阵营中冒Z个无名小子,|名Courage(勇气)Q?br />
发动对Java GC机制的批判,形势Z一变。C++阵营g处于全攻之势QJava阵营疲于防守Q只?br />
招架_“你们没有证据Q没有统计资?#8221;QŞ势很被动?/span>
垃圾攉(GC)不是一直被Java fans用来炫耀Q引以ؓ傲的优点么?怎么成了q了?我大惑不解,定睛
一看,才觉得此中颇有道理?/span>
首先QJava Swing库存在大量资源泄漏问题,q一点SUN非常清楚Q称之ؓbugsQ正在极力修正。但是看?br />
q里的问题恐怕不仅是库编写者的疏忽Q可能根源在于深层的机制Q未必能够轻易解冻I搞不好要伤筋动骨?br />
不过q个问题不是那么Ҏ(gu)QC++阵营觉得如果抓住Ҏ(gu)的弱Ҏ(gu)击,q是占了上风也没什么说服力。谁
没有~点呢?于是反其道而行之,猛烈dJava阵营觉得最得意的东西,Java的GC机制本n?/span>
首先来想一惻Imemory leak到底意味着什么。在C++中,new出来的对象没有deleteQ这导致了memory
leak。但是C++早就有了克服q一问题的办法——smart pointer。通过使用标准库里设计_致的auto_ptr
以及各种STL容器Q还有例如boost?差不多是个准标准库了)中的四个smart pointersQC++E序员只?br />
׃一个星期的旉学习最新的资料Q就可以拍着胸脯_“我写?/span>E序没有memory leak!”?/span>
相比之下QJavag更优UQ因Z一开始你׃用考虑什么特D的机制Q大胆地往前newQ自有GC替你
收拾D局。Java的GC实际上是JVM中的一个独立线E,采用不同的算?/span>{略来收集heap中那些不再有
reference指向的垃圑֯象所占用的内存。但是,通常情况下,GCU程的优先比较低,只有在当?/span>E序
I闲的时候才会被调度Q收集垃圾。当Ӟ如果JVM感到内存紧张了,JVM会主?/span>调用GC来收集垃圾,获取
更多的内存。请注意QJava的GC工作的时机是Q?. 当前E序不忙Q有I闲旉?. I闲内存不?br />
现在我们考虑一U常见的情况Q?/span>E序在紧张运行之中,没哟I闲旉lGC来运行,同时机器内存很大Q?br />
JVM也没有感到内存不Il果是什么?对了QGC形同虚设Q得不到调用。于是,内存被不断吞噬,而那?br />
早已l用不着的垃圑֯象仍在在宝贵的内存里睡大觉。例如:
class BadGc {
public void job1() {
String garbage = "I am a garbage, and just sleeping in your precious memory, " +
"how do you think you can deal with me? Daydreaming! HAHA!!!";
....
}
public void job2() {...}
...
...
public void job1000() {...}
public static void main(String[] args) {
bgc = new BadGc();
bgc.job1();
bgc.job2();
...
bgc.job1000();
}
}
q行中,虽然garbage对象在离开job1()之后Q就再也没有用了。但是因?/span>E序忙,内存q够用,所以GC?br /> 不到调度Qgarbage始终不会被回Ӟ直到E序q行到bgc.job1000()时还w在内存里嘲W你。没辙吧Q?/span>
好了Q我承认q段E序很傻。但是你不要以ؓq只是理Z的假设,恰恰相反Q大多数实用中的JavaE序都有
cM的效应。这是Z么JavaE序狂耗内存,而且好像l它多少内存吃都不够。你׃大笔的银子把内存
?28升到256Q再升到512Q结果是Q一旦执行复杂Q务,内存q是被轻易填满,而且多出来的q些内存只是
用来装垃圾,GCq是不给面子地千g唤不出来。等C的内存终于心力交瘁,GC才姗姗来q,收拾D局。?br />
且GC工作的方式也很不好评P一U方法是一旦有Z回收内存Q就把所有的垃圾都回收。你可以惌Q这?br />
花很长时?几百M的垃圑֕Q?Q如果你q时侯正在压下开炮的按钮QGC却叫了暂定,好了Q你{死吧!另一
U方法,得到Z之后Q回收一些内存,让JVM感到内存不那么紧张时收手。结果呢Q内存里始终有大批垃
圾,E序始终在半Mzȝ荡着。最后,GC可以每隔一D|间就q行一ơ,每次只回收一部分垃圾Q这是现?br />
大部分JVM的方式,l果是内存也费了,q动不动暂停几百毫秒。难啊!
反过来看看C++利用smart pointer达成的效果,一旦某对象不再被引用,pȝM容缓Q立d收内存。这
通常发生在关键Q务完成后的清?cleanup)时期Q不会媄响关键Q务的实时性,同时Q内存里所有的对象
都是有用的,l对没有垃圾I占内存。怎么P传统、朴素的C++是不是更胜一{?
据统计,目前的JavaE序q行期间占用的内存通常为对应C++E序?-20倍。除了其它的原因Q上面所说的是一?br /> 非常主要的因素。我们对memory leak如此愤恨Q不是因ؓ它导致大量的内存垃圾得不到清除吗Q如果有?br /> GC之后Q垃圾比以前q来势v汹,那么GC又有什么好处呢Q?/span>
当然QC++的smart pointer现在会用的Z多,所以现在的C++E序普遍存在更严重的memory leak问题?br /> 但是Q如果我奶奶跟舒马赫比赛车输掉了Q你能够埋怨那辆R子么Q?br /> http://www.594k.com/java/html/y2007m1/12051/
LiveJournal?9q始于校园中的项目,几个人出于爱好做了这样一个应用,以实C下功能:
LiveJournal采用了大量的开源YӞ甚至它本w也是一个开源Y件?
在上U后QLiveJournal实现了非常快速的增长Q?/p>
LiveJournal?台服务器发展?00台服务器Q这其中l历了无数的伤痛Q但同时也摸索出了解册些问题的Ҏ(gu)Q通过对LiveJournal的学习,可以让我们避免LJ曄犯过的错误,q且从一开始就对系l进行良好的设计Q以避免后期的痛苦?/p>
下面我们一步一步看LJ发展的脚步?/p>
一 台别人捐助的服务器,LJ最初就跑在上面Q就像Google开始时候用的破服务器一P值得我们敬。这个阶D,LJ的h以惊人的速度熟?zhn)的Unix的操 作管理,服务器性能出现q问题,不过q好Q可以通过一些小修小改应付过厅R在q个阶段里LJ把CGI升CFastCGI?/p>
最l问题出CQ网站越来越慢,已经无法通过优过化来解决的地步,需要更多的服务器,q时LJ开始提供付Ҏ(gu)务,可能是想通过q些钱来购买新的服务器,以解军_时的困境?br /> 毫无疑问Q当时LJ存在巨大的单炚w题,所有的东西都在那台服务器的铁皮盒子里装着?/p>
用付Ҏ(gu)务赚来的钱LJC两台服务器:一台叫做Kenny的Dell 6U机器用于提供Web服务Q一台叫做Cartman的Dell 6U服务器用于提供数据库服务?/p>
LJ有了更大的磁盘,更多的计资源。但同时|络l构q是非常单,每台机器两块|卡QCartman通过内网为Kenny提供MySQL数据库服务?br />
暂时解决了负载的问题Q新的问题又出现了:
又买了两収ͼKyle和StanQ这ơ都?U的,都用于提供Web服务。目前LJ一共有3台Web服务器和一台数据库服务器。这旉要在3台Web服务器上q行负蝲均横?/p>
LJ把Kenny用于外部的网养I使用mod_backhandq行负蝲均横?/p>
然后问题又出CQ?/p>
又买了一台数据库服务器。在两台数据库服务器上用了数据库同?Mysql支持的Master-Slave模式)Q写操作全部针对L据库Q通过BinlogQ主服务器上的写操作可以q速同步到从服务器上)Q读操作在两个数据库上同时进?也算是负载均横的一U吧)?/p>
实现同步时要注意几个事项Q?/p>
有钱了,当然要多C服务器。部|后快了没多久,又开始慢了。这ơ有更多的Web服务器,更多的数据库服务器,存在 IO与CPU争用。于是采用了BIG-IP作ؓ负蝲均衡解决Ҏ(gu)?/p>
现在服务器基本上够了Q但性能q是有问题,原因出在架构上?/p>
数据库的架构是最大的问题。由于增加的数据库都是以Slave模式d到应用内Q这样唯一的好处就是将L作分布到了多台机器,但这样带来的后果是写操作被大量分发Q每台机器都要执行,服务器越多,费p大,随着写操作的增加Q用于服务读操作的资源越来越?/p>
׃台分布到两台
最l效?/p>
现在我们发现Q我们ƈ不需要把q些数据在如此多的服务器上都保留一份。服务器上已l做了RAIDQ数据库也进行了备䆾Q这么多的备份完全是对资源的费Q属于冗余极端过度。那Z么不把数据分布存储呢Q?/p>
问题发现了,开始考虑如何解决。现在要做的是把不同用L数据分布C同的服务器上q行存储Q以实现数据的分布式存储Q让每台机器只ؓ相对固定的用h务,以实现^行的架构和良好的可扩展性?/p>
?了实现用户分l,我们需要ؓ每一个用户分配一个组标记Q用于标记此用户的数据存攑֜哪一l数据库服务器中。每l数据库׃个master及几个slave l成Qƈ且slave的数量在2-3収ͼ以实现系l资源的最合理分配Q既保证数据L作分布,又避免数据过度冗余以及同步操作对pȝ资源的过度消耗?/p>
׃収ͼ一l)中心服务器提供用户分l控制。所有用L分组信息都存储在q台机器上,所有针对用L操作需要先查询q台机器得到用户的组P然后再到相应的数据库l中获取数据?/p>
q样的用h构与目前LJ的架构已l很相像了?/p>
在具体的实现旉要注意几个问题:
问题Q?/p>
对于Master-Slave模式的单炚w题,LJ采取了Master-Master模式来解冟뀂所谓Master-Master实际上是人工实现的,q不是由MySQL直接提供的,实际上也是两台机器同时是MasterQ也同时是SlaveQ互相同步?/p>
Master-Master实现旉要注意:
解决Ҏ(gu)Q?br />
Master-Master模式q有一U用法,q种Ҏ(gu)与前一U相比,仍然保持两台机器的同步,但只有一台机器提供服务(d写)Q在每天晚上的时候进行轮换,或者出现问题的时候进行切换?/p>
现在插播一条广告,MyISAM VS InnoDB?/p>
使用InnoDBQ?/p>
使用MyISAMQ?/p>
d我写q?a >一文章介lmemcachedQ它?yu)是由LJ的团队开发的一Ƅ存工P以key-value的方式将数据存储到分布的内存中。LJ~存的数据:
如何建立~存{略Q?/p>
想缓存所有的东西Q那是不可能的,我们只需要缓存已l或者可能导致系l瓶颈的地方Q最大程度的提交pȝq行效率。通过对MySQL的日志的分析我们可以扑ֈ~存的对象?/p>
~存的缺点?
在数据包U别使用BIG-IPQ但BIG-IPq不知道我们内部的处理机Ӟ无法判断由哪台服务器对这些请求进行处理。反向代理ƈ不能很好的vC用,不是已经够快了,是达不到我们想要的效果?/p>
所以,LJ又开发了Perlbal。特点:
LJ使用开源的MogileFS作ؓ分布式文件存储系l。MogileFS使用非常单,它的主要设计思想是:
到目前ؓ止就q么多了Q更多文可以在http://www.danga.com/words/扑ֈ?a >Danga.com?a >LiveJournal.com?同学们拿q个文参加了两ơMySQL ConQ两ơOS ConQ以及众多的其它会议Q无U的把他们的l验分n出来Q值得我们学习。在web2.0时代快速开发得到大家越来越多的重视Q但良好的设计仍是每一个应 用的基础Q希望web2.0们在成长为Top500|站的\上,不要因ؓ架构ȝ了网站的发展?/p> http://blog.csdn.net/xmr_gxcfe/archive/2007/09/14/1785292.aspx
J2EE开发中大量的专业羃略语很是让hqhQ尤其是跟一些高手讨论问题的时候,三分钟就被h家满口的专业术语h了,PO VO BO DTO POJO DAOQ一大堆的就来了Q听q老罗对这U现象的批判的朋友会会心一W)?/p>
首先声明偶也不是什么高手,以下ȝ都是自己的体会。不对之处请(zhn)多指教?/p>
POQ?br>persistant object持久对象
最形象的理解就是一个PO是数据库中的一条记录?br>好处是可以把一条记录作Z个对象处理,可以方便的{为其它对象?br>
BOQ?br>business object业务对象
主要作用是把业务逻辑装Z个对象。这个对象可以包括一个或多个其它的对象?br>比如一个简历,有教育经历、工作经历、社会关pȝ{?br>我们可以把教育经历对应一个POQ工作经历对应一个POQ社会关pd应一个PO?br>建立一个对应简历的BO对象处理历,每个BO包含q些PO?br>q样处理业务逻辑Ӟ我们可以针对BOd理?br>
VO Q?br>value object值对?br>ViewObject表现层对?br>
主要对应界面昄的数据对象。对于一个WEB面Q或者SWT、SWING的一个界面,用一个VO对象对应整个界面的倹{?br>
DTO Q?br>Data Transfer Object数据传输对象
主要用于q程调用{需要大量传输对象的地方?br>比如我们一张表?00个字D,那么对应的PO有100个属性?br>但是我们界面上只要显C?0个字D,
客户端用WEB service来获取数据,没有必要把整个PO对象传递到客户端,
q时我们可以用只有q?0个属性的DTO来传递结果到客户端,q样也不会暴露服务端表结?到达客户端以后,如果用这个对象来对应界面昄Q那此时它的w䆾p{为VO
POJO Q?br>plain ordinary java object 单java对象
个h感觉POJO是最常见最多变的对象,是一个中间对象,也是我们最常打交道的对象?br>
一个POJO持久化以后就是PO
直接用它传递、传递过E中是DTO
直接用来对应表示层就是VO
DAOQ?br>data access object数据讉K对象
q个大家最熟?zhn)Q和上面几个O区别最大,基本没有互相转化的可能性和必要.
主要用来装Ҏ(gu)据库的访问。通过它可以把POJO持久化ؓPOQ用POl装出来VO、DTO
ȝ下我认ؓ一个对象究竟是什么O要看具体环境Q在不同的层、不同的应用场合Q对象的w䆾也不一P而且对象w䆾的{化也是很自然的。就像你对老婆来说是老公Q对父母来说是子女。设计这些概늚初衷不是Z唬h而是Z更好的理解和处理各种逻辑Q让大家能更好的ȝ面向对象的方式处理问?
大家千万不要陷入q度设计Q大可不必ؓ了设计而设计一定要在代码中区分各个对象。一句话技术是为应用服务的?br>
Ƣ迎指正?br>
![]() |
|
原文地址Q?a id="LinkUrl" href="/BlueDavy/archive/2006/05/28/48593.html" target="_blank">http://www.tkk7.com/BlueDavy/archive/2006/05/28/48593.html摘要:插g开发框架其实和目前开源界行的MVC框架之类的相同,都决定了Zq个框架的开发方式,如基于MVC框架Q就会按照MVC思想来进行开发,而插件开发框架呢Q也是同样如此,p求基于插件的方式来进行开发,不过插g开发框架和MVC框架又有不同Q插件开发框架是一个可以成为系l基架构的框Ӟ而MVC框架通常来讲不以成为,如在目前的MVC框架Webwork、Struts上我们通常都需要加上Spring、Hibernate来构成系l完整的基础架构Q这个时候由于MVC框架的实现是没有标准可参照的Q就造成了在各种pȝ中Ş成了不同的但很类似的基础架构Q但却造成了无法复用的现象Q插件开发框架则是作为统一pȝ基础架构的一U开发方式,它得系l的复用成ؓ了可能,而同时由于插件开发框架对于动态性的支持Q得系l更加的灉|和可扩展。来看看一个插件开发框Ӟ应该提供些什么东西,作ؓ改变pȝ架构思想的框Ӟ插g框架需要考虑很多斚wQ如开发、测试、部|等Qȝ下来一个插件框架应提供插g的开发规范;插g开发、调试的IDEQ?/span> |