JavaforHighPerformanceComputingjava.
nio:HighPerformanceI/OforJavahttp://www.
hpjava.
org/courses/arlInstructor:BryanCarpenterPervasiveTechnologyLabsIndianaUniversityNIO:NewI/OPriortotheJ2SE1.
4releaseofJava,I/Ohadbecomeabottleneck.
JITperformancewasreachingthepointwhereonecouldstarttothinkofJavaasaplatformforHighPerformancecomputation,buttheoldjava.
iostreamclasseshadtoomanysoftwarelayerstobefast—thespecificationimpliedmuchcopyingofsmallchunksofdata;therewasnowaytomultiplexdatafrommultiplesourceswithoutincurringthreadcontextswitches;alsotherewasnowaytoexploitmodernOStricksforhighperformanceI/O,likememorymappedfiles.
NewI/Ochangesthatbyproviding:AhierarchyofdedicatedbufferclassesthatallowdatatobemovedfromtheJVMtotheOSwithminimalmemory-to-memorycopying,andwithoutexpensiveoverheadslikeswitchingbyteorder;effectivelybufferclassesgiveJavaa"window"onsystemmemory.
Aunifiedfamilyofchannelclassesthatallowdatatobefeddirectlyfrombufferstofilesandsockets,withoutgoingthroughtheintermediariesoftheoldstreamclasses.
Afamilyofclassestodirectlyimplementselection(AKAreadinesstesting,AKAmultiplexing)overasetofchannels.
NIOalsoprovidesfilelockingforthefirsttimeinJava.
ReferencesTheJavaNIOsoftwareispartofJ2SE1.
4andlater,fromhttp://java.
sun.
com/j2se/1.
4Onlinedocumentationisat:http://java.
sun.
com/j2se/1.
4/nioThereisanauthoritativebookfromO'Reilly:"JavaNIO",RonHitchens,2002BuffersBuffersABufferobjectisacontainerforafixedamountofdata.
Itbehavessomethinglikeabyte[]array,butisencapsulatedinsuchawaythattheinternalstoragecanbeablockofsystemmemory.
Thusaddingdatato,orextractingitfrom,abuffercanbeaverydirectwayofgettinginformationbetweenaJavaprogramandtheunderlyingoperatingsystem.
AllmodernOS'sprovidevirtualmemorysystemsthatallowmemoryspacetobemappedtofiles,sothisalsoenablesaverydirectandhigh-performanceroutetothefilesystem.
Thedatainabuffercanalsobeefficientlyreadfrom,orwrittento,asocketorpipe,enablinghighperformancecommunication.
ThebufferAPIsallowyoutoreadorwritefromaspecificlocationinthebufferdirectly;theyalsoallowrelativereadsandwrites,similartosequentialfileaccess.
Thejava.
nio.
BufferHierarchyTheByteBufferClassThemostimportantbufferclassinpracticeisprobablytheByteBufferclass.
Thisrepresentsafixed-sizevectorofprimitivebytes.
Importantmethodsonthisclassinclude:byteget()byteget(intindex)ByteBufferget(byte[]dst)ByteBufferget(byte[]dst,intoffset,intlength)ByteBufferput(byteb)ByteBufferput(intindex,byteb)ByteBufferput(byte[]src)ByteBufferput(byte[]src,intoffset,intlength)ByteBufferput(ByteBuffersrc)FilePositionandLimitApartfromformswithanindexparameter,theseareallrelativeoperations:theygetdatafrom,orinsertdatainto,thebufferstartingatthecurrentpositioninthebuffer;theyalsoupdatethepositiontopointtothepositionafterthereadorwrittendata.
Thepositionpropertyislikethefilepointerinsequentialfileaccess.
ThesuperclassBufferhasmethodsforexplicitlymanipulatingthepositionandrelatedpropertiesofbuffers,e.
g:intposition()Bufferposition(intnewPosition)intlimit()Bufferlimit(intnewLimit)TheByteBufferorBufferreferencesreturnedbythesevariousmethodsaresimplyreferencestothisbufferobject,notnewbuffers.
Theyareprovidedtosupportcrypticinvocationchaining.
Feelfreetoignorethem.
Thelimitpropertydefineseitherthelastspaceavailableforwriting,orhowmuchdatahasbeenwrittentothefile.
Afterfinishingwritingaflip()methodcanbecalledtosetlimittothecurrentvalueofposition,andresetpositiontozero,readyforreading.
Variousoperationsimplicitlyworkonthedatabetweenpositionandlimit.
CreatingBuffersFourinterestingfactorymethodscanbeusedtocreateanewByteBuffer:ByteBufferallocate(intcapacity)ByteBufferallocateDirect(intcapacity)ByteBufferwrap(byte[]array)ByteBufferwrap(byte[]array,intoffset,length)TheseareallstaticmethodsoftheByteBufferclass.
allocate()createsaByteBufferwithanordinaryJavabackingarrayofsizecapacity.
allocateDirect()—perhapsthemostinterestingcase—createsadirectByteBuffer,backedbycapacitybytesofsystemmemory.
Thewrap()methodscreateByteBuffer'sbackedbyallorpartofanarrayallocatedbytheuser.
Theothertypedbufferclasses(CharBuffer,etc)havesimilarfactorymethods,excepttheydon'tsupporttheimportantallocateDirect()method.
OtherPrimitiveTypesinByteBuffer'sItispossibletowriteotherprimitivetypes(char,int,double,etc)toaByteBufferbymethodslike:ByteBufferputChar(charvalue)ByteBufferputChar(intindex,charvalue)ByteBufferputInt(intvalue)ByteBufferputInt(intindex,intvalue)…TheputChar()methodsdoabsoluteorrelativewritesofthetwobytesinaJavachar,theputInt()methodswrite4bytes,andsoon.
OfcoursetherearecorrespondinggetChar(),getInt(),…methods.
Thesegiveyoufun,unsafewaysofcoercingbytesofoneprimitivetypetoanothertype,bywritingdataasonetypeandreadingthemasanother.
Butactuallythisisn'ttheinterestingbit—thiswasalwayspossiblewiththeoldjava.
ioDataStream's.
TheinterestingbitisthatthenewByteBufferclasshasamethodthatallowsyoutosetthebyteorder…Endian-nessWhenidentifyinganumerictypelikeintordoublewithasequenceofbytesinmemory,onecaneitherputthemostsignificantbytefirst(big-endian),ortheleastsignificantbytefirst(little-endian).
BigEndian:SunSparc,PowerPCCPU,numericfieldsinIPheaders,…LittleEndian:IntelprocessorsInjava.
io,numerictypeswerealwaysrenderedtostreaminbig-endianorder.
Createsaseriousbottleneckwhenwritingorreadingnumerictypes.
Implementationstypicallymustapplybytemanipulationcodetoeachitem,toensurebytesarewritteninthecorrectorder.
Injava.
nio,theprogrammerspecifiesthebyteorderasapropertyofaByteBuffer,bycallingoneof:myBuffer.
order(ByteOrder.
BIG_ENDIAN)myBuffer.
order(ByteOrder.
LITTLE_ENDIAN)myBuffer.
order(ByteOrder.
nativeOrder())Providedtheprogrammerensuresthebyteordersetforthebufferagreeswiththenativerepresentationforthelocalprocessor,numericdatacanbecopiedbetweenJVM(whichwillusethenativeorder)andbufferbyastraightblockmemorycopy,whichcanbeextremelyfast—abigwinforNIO.
ViewBuffersByteBufferhasnomethodsforbulktransferofarraysotherthantypebyte[].
Instead,createaviewof(aportionof)aByteBufferasanyotherkindoftypedbuffer,thenusethebulktransfermethodsonthatview.
FollowingmethodsofByteBuffercreateviews:CharBufferasCharBuffer()IntBufferasIntBuffer()…TocreateaviewofjustaportionofaByteBuffer,setpositionandlimitappropriatelybeforehand—thecreatedviewonlycoverstheregionbetweenthese.
YoucannotcreateviewsoftypedbuffersotherthanByteBuffer.
Youcancreateanotherbufferthatrepresentsasubsectionofanybuffer(withoutchangingelementtype)byusingtheslice()method.
Forexample,writinganarrayoffloatstoabytebuffer,startingatthecurrentposition:float[]array;…FloatBufferfloatBuf=byteBuf.
asFloatBuffer();floatBuf.
put(array);ChannelsChannelsAchannelisanewabstractioninjava.
nio.
Inthepackagejava.
nio.
channels.
Channelsareahigh-levelversionofthefile-descriptorsfamiliarfromPOSIX-compliantoperatingsystems.
SoachannelisahandleforperformingI/Ooperationsandvariouscontroloperationsonanopenfileorsocket.
ForthosefamiliarwithconventionalJavaI/O,java.
nioassociatesachannelwithanyRandomAccessFile,FileInputStream,FileOutputStream,Socket,ServerSocketorDatagramSocketobject.
ThechannelbecomesapeertotheconventionalJavahandleobjects;theconventionalobjectsstillexist,andingeneralretaintheirrole—thechanneljustprovidesextraNIO-specificfunctionality.
NIObufferobjectscanwrittentoorreadfromchannelsdirectly.
Channelsalsoplayanessentialroleinreadinessselection,discussedinthenextsection.
SimplifiedChannelHierarchySomeofthe"inheritance"arcshereareindirect:wemissedoutsomeinterestinginterveningclassesandinterfaces.
OpeningChannelsSocketchannelclasseshavestaticfactorymethodscalledopen(),e.
g.
:SocketChannelsc=SocketChannel.
open();Sc.
connect(newInetSocketAddress(hostname,portnumber));Filechannelscannotbecreateddirectly;firstuseconventionalJavaI/OmechanismstocreateaFileInputStream,FileOutputStream,orRandomAccessFile,thenapplythenewgetChannel()methodtogetanassociatedNIOchannel,e.
g.
:RandomAccessFileraf=newRandomAccessFile(filename,"r");FileChannelfc=raf.
getChannel();UsingChannelsAnychannelthatimplementstheByteChannelinterface—i.
e.
allchannelsexceptServerSocketChannel—providearead()andawrite()instancemethod:intread(ByteBufferdst)intwrite(ByteBuffersrc)Thesemaylookreminiscentoftheread()andwrite()systemcallsinUNIX:intread(intfd,void*buf,intcount)intwrite(intfd,void*buf,intcount)TheJavaread()attemptstoreadfromthechannelasmanybytesasthereareremainingtobewritteninthedstbuffer.
Returnsnumberofbytesactuallyread,or-1ifend-of-stream.
Alsoupdatesdstbufferposition.
Similarlywrite()attemptstowritetothechannelasmanybytesasthereareremaininginthesrcbuffer.
Returnsnumberofbytesactuallyread,andupdatessrcbufferposition.
Example:CopyingoneChanneltoAnotherThisexampleassumesasourcechannelsrcandadestinationchanneldest:ByteBufferbuffer=ByteBuffer.
allocateDirect(BUF_SIZE);while(src.
read(buffer)!
=-1)buffer.
flip(Preparereadbufferfor"draining"while(buffer.
hasRemaining(dest.
write(buffer)buffer.
clear(Emptybuffer,readytoreadnextchunk.
}Noteawrite()call(oraread()call)mayormaynotsucceedintransferringwholebufferinasinglecall.
Henceneedforinnerwhileloop.
ExampleintroducestwonewmethodsonBuffer:hasRemaining()returnstrueifpositionJava.
FileChannelhasamethod:MappedByteBuffermap(MapModemode,longposition,longsize)modeshouldbeoneofMapMode.
READ_ONLY,MapMode.
READ_WRITE,MapMode.
PRIVATE.
ThereturnedMappedByteBuffercanbeusedwhereveranordinaryByteBuffercan.
Scatter/GatherOftencalledvectoredI/O,thisjustmeansyoucanpassanarrayofbufferstoareadorwriteoperation;theoverloadedchannelinstancemethodshavesignatures:longread(ByteBuffer[]dsts)longread(ByteBuffer[]dsts,intoffset,intlength)longwrite(ByteBuffer[]srcs)longwrite(ByteBuffer[]srcs,intoffset,intlength)Thefirstformofread()attemptstoreadenoughdatatofillallbuffersinthearray,anddividesitbetweenthem,inorder.
Thefirstformofwrite()attemptstoconcatenatetheremainingdatainallbuffersandwriteit.
Theargumentsoffsetandlengthselectasubsetofbuffersfromthearrays(not,say,anintervalwithinbuffers).
SocketChannelsAsmentionedatthebeginningofthissection,socketchannelsarecreateddirectlywiththeirownfactorymethodsIfyouwanttomanageasockedconnectionasaNIOchannelthisistheonlyoption.
CreatingNIOsocketchannelimplicitlycreatesapeerjava.
netsocketobject,but(contrarytothesituationwithfilehandles)theconverseisnottrue.
Aswithfilechannels,socketchannelscanbemorecomplicatedtoworkwiththanthetraditionaljava.
netsocketclasses,butprovidemuchofthehard-boiledflexibilityyougetprogrammingsocketsinC.
Themostnotablenewfacilitiesarethatnowsocketcommunicationscanbenon-blocking,theycanbeinterrupted,andthereisaselectionmechanismthatallowsasinglethreadtodomultiplexservicingofanynumberofchannels.
BasicSocketChannelOperationsTypicaluseofaserversocketchannelfollowsapatternlike:ServerSocketChannelssc=ServerSocketChannel.
open();ssc.
socket().
bind(newInetSocketAddress(port));while(true)SocketChannelsc=ssc.
accept(processatransactionwithclientthroughsc…}Theclientdoessomethinglike:SocketChannelsc=SocketChannel.
open();sc.
connect(newInetSocketAddr(serverName,port));…initiateatransactionwithserverthroughsc…Theelidedcodeabovewilltypicallybeusingread()andwrite()callsontheSocketChanneltoexchangedatabetweenclientandserver.
Sotherearefourimportantoperations:accept(),connect(),write(),read().
NonblockingOperationsBycallingthemethodsocket.
configureBlocking(false);youputasocketintononblockingmode(callingagainwithargumenttruerestorestoblockingmode,andsoon).
Innon-blockingmode:Aread()operationonlytransfersdatathatisimmediatelyavailable.
Ifnodataisimmediatelyavailableitreturns0.
Similarly,ifdatacannotbeimmediatelywrittentoasocket,awrite()operationwillimmediatelyreturn0.
Foraserversocket,ifnoclientiscurrentlytryingtoconnect,theaccept()methodimmediatelyreturnsnull.
Theconnect()methodismorecomplicated—generallyconnectionswouldalwaysblockforsomeintervalwaitingfortheservertorespond.
Innon-blockingmodeconnect()generallyreturnsfalse.
Butthenegotiationwiththeserverisneverthelessstarted.
ThefinishConnect()methodonthesamesocketshouldbecalledlater.
Italsoreturnsimmediately.
Repeatuntilitreturntrue.
InterruptibleOperationsThestandardchannelsinNIOareallinterruptible.
Ifathreadisblockedwaitingonachannel,andthethread'sinterrupt()methodiscalled,thechannelwillbeclosed,andthethreadwillbewokenandsentaClosedByInterruptException.
Toavoidraceconditions,thesamewillhappenifanoperationonachannelisattemptedbyathreadwhoseinterruptstatusisalreadytrue.
Seethelectureonthreadsforadiscussionofinterrupts.
ThisrepresentsprogressovertraditionalJavaI/O,whereinterruptionofblockingoperationswasnotguaranteed.
OtherFeaturesofChannelsFilechannelsprovideaquitegeneralfilelockingfacility.
Thisispresumablyimportanttomanyapplications(databaseapplications),butlessobviouslysotoHPCoperations,sowedon'tdiscussithere.
ThereisaDatagramChannelforsendingUDP–stylemessages.
Thismaywellbeimportantforhighperformancecommunications,butwedon'thavetimetodiscussit.
Thereisaspecialchannelimplementationrepresentingakindofpipe,whichcanbeusedforinter-threadcommunication.
SelectorsReadinessSelectionPriortoNewI/O,Javaprovidednostandardwayofselecting—fromasetofpossiblesocketoperations—justtheonesthatarecurrentlyreadytoproceed,sothereadyoperationscanbeimmediatelyserviced.
OneapplicationwouldbeinimplementinganMPI-likemessagepassingsystem:ingeneralincomingmessagesfrommultiplepeersmustbeconsumedastheyarriveandfedintoamessagequeue,untiltheuserprogramisreadytohandlethem.
PreviouslyonecouldachieveequivalenteffectsinJavabydoingblockingI/Ooperationsinseparatethreads,thenmergingtheresultsthroughJavathreadsynchronization.
Butthiscanbeinefficientbecausethreadcontextswitchingandsynchronizationisquiteslow.
OnewayofachievingthedesiredeffectinNewI/Owouldbesetallthechannelsinvolvedtonon-blockingmode,anduseapollinglooptowaituntilsomearereadytoproceed.
Amorestructured—andpotentiallymoreefficient—approachistouseSelectors.
InmanyflavorsofUNIXthisisachievedbyusingtheselect()systemcall.
ClassesInvolvedinSelectionSelectioncanbedoneonanychannelextendingSelectableChannel—amongstthestandardchannelsthismeansthethreekindsofsocketchannel.
Theclassthatsupportstheselect()operationitselfisSelector.
Thisisasortofcontainerclassforthesetofchannelsinwhichweareinterested.
ThelastclassinvolvedisSelectionKey,whichissaidtorepresentthebindingbetweenachannelandaselector.
InsomesenseitispartoftheinternalrepresentationoftheSelector,buttheNIOdesignersdecidedtomakeitanexplicitpartoftheAPI.
SettingUpSelectorsAselectoriscreatedbytheopen()factorymethod.
ThisisnaturallyastaticmethodoftheSelectorclass.
Achannelisaddedtoaselectorbycallingthemethod:SelectionKeyregister(Selectorsel,intops)This,slightlyoddly,isaninstancemethodoftheSelectableChannelclass—youmighthaveexpectedtheregister()methodtobeamemberofSelector.
Hereopsisabit-setrepresentingtheinterestsetforthischannel:composedbyoringtogetheroneormoreof:SelectionKey.
OP_READSelectionKey.
OP_WRITESelectionKey.
OP_CONNECTSelectionKey.
OP_ACCEPTAchanneladdedtoaselectormustbeinnonblockingmode!
Theregister()methodreturnstheSelectionKeycreatedSincethisautomaticallygetsstoredintheSelector,soinmostcasesyouprobablydon'tneedtosavetheresultyourself.
ExampleHerewecreateaselector,andregisterthreepre-existingchannelstotheselector:Selectorselector=Selector.
open();channel1.
register(selector,SelectionKey.
OP_READ);channel2.
register(selector,SelectionKey.
OP_WRITE);channel3.
register(selector,SelectionKey.
OP_READSelectionKey.
OP_WRITE);Forchannel1theinterestsetisreadsonly,forchannel2itiswritesonly,forchannel3itisreadsandwrites.
Notechannel1,channel2,channel3mustallbeinnon-blockingmodeatthistime,andmustremaininthatmodeaslongastheyareregisteredinanyselector.
Youremoveachannelfromaselectorbycallingthecancel()methodoftheassociatedSelectionKey.
select()andtheSelectedKeySetToinspectthesetofchannels,toseewhatoperationsarenewlyreadytoproceed,youcalltheselect()methodontheselector.
Thereturnvalueisaninteger,whichwillbezeroifnostatuschangesoccurred.
Moreinterestingthanthereturnvalueisthesideeffectthismethodhasonthesetofselectedkeysembeddedintheselector.
Touseselectors,youmustunderstandthataselectormaintainsaSetobjectrepresentingthisselectedkeysset.
Becauseeachkeyisassociatedwithachannel,thisisequivalenttoasetofselectedchannels.
Thesetofselectedkeysisdifferentfrom(presumablyasubsetof)theregisteredkeyset.
Eachtimetheselect()methodiscalleditmayaddnewkeystotheselectedkeyset,asoperationsbecomereadytoproceed.
You,astheprogrammer,areresponsibleforexplicitlyremovingkeysfromtheselectedkeysetbelongingtotheselector,asyoudealwithoperationsthathavebecomeready.
ReadySetsThisisquitecomplicatedalready,butthereisonemorecomplication.
Wesawthateachkeyintheregisteredkeysethasanassociatedinterestset,whichisasubsetofthe4possibleoperationsonsockets.
Similarlyeachkeyintheselectedkeysethasanassociatedreadyset,whichisasubsetoftheinterestset—representingtheactualoperationsthathavebeenfoundreadytoproceed.
Besidesaddingnewkeystotheselectedkeyset,aselect()operationmayaddnewoperationstothereadysetofakeyalreadyintheselectedkeyset.
Assumingtheselectedkeysetwasnotclearedafteraprecedingselect().
YoucanextractthereadysetfromaSelectionKeyasabit-set,byusingthemethodreadyOps().
Oryoucanusetheconveniencemethods:isReadable()isWriteable()isConnectable()isAcceptable()whicheffectivelyreturnthebitsofthereadysetindividually.
APatternforUsingselect()…registersomechannelswithselector…while(true)selector.
select(Iteratorit=selector.
selectedKeys().
iterator(while(it.
hasNext(SelectionKeykey=it.
next(if(key.
isReadable(performread()operationonkey.
channel(if(key.
isWriteable(performwrite()operationonkey.
channel(if(key.
isConnectable(performconnect()operationonkey.
channel(if(key.
isAcceptable(performaccept()operationonkey.
channel(it.
remove(RemarksThisgeneralpatternwillprobablyserveformostusesofselect():Performselect()andextractthenewselectedkeysetForeachselectedkey,handletheactionsinitsreadysetRemovetheprocessedkeyfromtheselectedkeysetNotetheremove()operationonanIteratorremovesthecurrentitemfromtheunderlyingcontainer.
Moregenerally,thecodethathandlesareadyoperationmayalsoalterthesetofchannelsregisteredwiththeselectore.
gafterdoinganaccept()youmaywanttoregisterthereturnedSocketChannelwiththeselector,towaitforread()orwrite()operations.
Inmanycasesonlyasubsetofthepossibleoperationsread,write,accept,connectareeverininterestsetsofkeysregisteredwiththeselector,soyouwon'tneedall4tests.
KeyAttachmentsOneproblemwiththepatternaboveisthatwhenit.
next()returnsakey,thereisnoconvenientwayofgettinginformationaboutthecontextinwhichtheassociatedchannelwasregisteredwiththeselector.
Forexamplechannel1andchannel3arebothregisteredforOP_READ.
Buttheactionthatshouldbetakenwhenthereadbecomesreadymaybequitedifferentforthetwochannels.
Youneedaconvenientwaytodeterminewhichchannelthereturnedkeyisboundto.
Youcanspecifyanarbitraryobjectasanattachmenttothekeywhenyoucreateit;laterwhenyougetthekeyfromtheselectedset,youcanextracttheattachment,anduseitscontentintodecidewhattodo.
Atitsmostbasictheattachmentmightjustbeanindexidentifyingthechannel.
SimplisticUseofKeyAttachmentschannel1.
register(selector,SelectionKey.
OP_READ,newInteger(1)attachment…channel3.
register(selector,SelectionKey.
OP_READSelectionKey.
OP_WRITE,newInteger(3)attachment…while(true)Iteratorit=selector.
selectedKeys().
iterator(SelectionKeykey=it.
next(if(key.
isReadable(switch(((Integer)key.
channel().
attachment()).
value(case1actionappropriatetochannel1case3actionappropriatetochannel3ConclusionWebrieflyvisitedseveraltopicsinNewI/OthatarelikelytobeinterestingforHPCwithJava.
Sometopicsthatarelessobviouslyrelevantweskipped,likefilelocking,andregularexpressions.
Alsowedidn'tcoverdatagramchannels,whichmaywellberelevant.
NewI/OhasbeenwidelyhailedasanimportantstepforwardingettingseriousperformanceoutoftheJavaplatform.
Seethepaper:"MPJava:High-PerformanceMessagePassinginJavausingjava.
nio"WilliamPughandJaimeSpaccoForagoodexampleofhowNewI/Omayaffectthe"JavaforHPC"landscape.
六一云 成立于2018年,归属于西安六一网络科技有限公司,是一家国内正规持有IDC ISP CDN IRCS电信经营许可证书的老牌商家。大陆持证公司受大陆各部门监管不好用支持退款退现,再也不怕被割韭菜了!主要业务有:国内高防云,美国高防云,美国cera大带宽,香港CTG,香港沙田CN2,海外站群服务,物理机,宿母鸡等,另外也诚招代理欢迎咨询。官网www.61cloud.net最新直销劲爆...
TNAHosting是一家成立于2012年的国外主机商,提供VPS主机及独立服务器租用等业务,其中VPS主机基于OpenVZ和KVM架构,数据中心在美国芝加哥机房。目前,商家在LET推出芝加哥机房大硬盘高配VPS套餐,再次刷新了价格底线,基于OpenVZ架构,12GB内存,500GB大硬盘,支持月付仅5美元起。下面列出这款VPS主机配置信息。CPU:4 cores内存:12GB硬盘:500GB月流...
Hostodo 算是比较小众的海外主机商,这次九月份开学季有提供促销活动。不过如果我们有熟悉的朋友应该知道,这个服务商家也是比较时间久的,而且商家推进活动比较稳,每个月都有部分活动。目前有提供机房可选斯波坎、拉斯维加斯和迈阿密。从机房的地理位置和实际的速度,中文业务速度应该不是优化直连的,但是有需要海外业务的话一般有人选择。以前一直也持有他们家的年付12美元的机器,后来用不到就取消未续约。第一、开...
java抽奖程序为你推荐
支持ipad支持ipad支持ipadiphonewifi苹果wifi版和4G版是什么意思,有什么区别吗xp系统关闭445端口xp中,如何关闭掉一些没有用的端口,请高手解答?谷歌sb为什么搜索SB第一个是google?迅雷快鸟用迅雷快鸟提示:您所在的网络暂不支持迅雷快鸟firefoxflash插件火狐浏览器adobe flash player装了不能用迅雷下载速度迅雷下载速度与什么有关?google搜图google的直接搜索图片的功能为什么没了
lamp 阿里云os 狗爹 国外php主机 tier iisphpmysql permitrootlogin 云主机51web 怎样建立邮箱 softbank邮箱 域名评估 服务器合租 空间合租 如何用qq邮箱发邮件 空间购买 移动服务器托管 宏讯 数据库空间 全能空间 杭州电信宽带优惠 更多