<?xml version="1.0" encoding="UTF-8"?>
<posts type="array">
  <post>
    <body>En Java proces har et lineart stigende hukommelsens forbrug. En uheldig arkitektur beslutning afstedkommer en konstant &#248;gning af hukommelses forbrug ved eksekvering af processen.  Beslutningen resulterer i en begr&#230;nset k&#248;retid afh&#230;ngigt af den valgte m&#230;ngde af hukommelse hvori processen eksekveres. 

En proces med ca. 4000 enheder optager ca. femhundrede megabytes. Et ansl&#229;et estimat p&#229; ca. 10.000 enheder vil optage ca. femtenhundrede megabytes og s&#229; fremdeles. Det betyder at man skal bruge virkeligt meget hukommelse for at k&#248;re programmet f&#230;rdig. 

Kan det lade sig g&#248;re og hvad er hukommelse? 

Alle Java processer eksekveres i en JVM, container, som har automatisk hukommelsesstyring. Den allokerede m&#230;ngde hukommelsen som er afsat til at indeholde programmet kaldes Heap Memory. Denne container kan dekoreres med flag som bestemmer fordelingen mellem de enkelte hukommelsesomr&#229;der der allokeres til hver applikation. 

Der findes forskellige omr&#229;der eller pools under den f&#230;lles betegnelse Heap Memory. Nogle af disse omr&#229;der holder p&#229; nye objekter og andre p&#229; gamle. Heap er delt op omkring to hovedomr&#229;der, heap space og non heap space.  

* Eden Space - Pulje, hvorfra hukommelse er oprindelig blev tildelt for de fleste objekter.  
* Survivor Space - Pool indeholder objekter, der har overlevet GC for Paradis rummet.
* Tenured generation - Pool indeholder objekter, der har eksisteret i nogen tid i den overlevende plads
* Faste Generation - Besidder alle de reflekterende data i den virtuelle maskine selv, s&#229;som klasse og metode objekter. Med JVMs at bruge klasse deling af data, denne generation er opdelt i read-only og read-write omr&#229;der.
* Code cache - Memory anvendes til udarbejdelse og opbevaring af native kode
* Perm Gen &#8211; Stak eller information om alle de objekter som er placeret i hukommelsen. 


Den f&#230;lles samlede m&#230;ngde hukommelse er den vigtigste faktor. Men hukommelsen har ogs&#229; direkte indvirkning p&#229; garbage collection. GC er den proces som administrer hukommelsen og sikre at de programm&#248;rer som skriver Java kode ikke beh&#248;ver at vide noget om allokering af hukommelse.     

Ydeevnen ved garbage collection h&#230;nger t&#230;t sammen med hukommelsen. N&#229;r hukommelsen n&#229;r en vis udfyldings gr&#230;nse kaldes GC af systemet med j&#230;vne mellemrum. Under en garbage collection re-allokeres alle objekter i heap. Nogle objekter flyttes mellem forskellige pools mens andre fjernes helt. Heap vokser eller falder ved hver GC for at bibeholde forholdet mellem fri plads og de levende objekter. Fx indeholder Perm information om objekter i Eden og dermed kan man begynde at ane et m&#248;nster om relationer mellem de enkelte rum. 

Normalt er det god skik at stille JVM MIN til 512m og MAX til det samme. Ved denne indstilling kan systemet starte hurtigt og bruger ikke tid p&#229; store re-allokeringer af hukommelse ved GC. 
&lt;pre&gt;
-Xms512m
-Xmx512m
&lt;/pre&gt;

Hvis applikationen h&#230;nger eller f&#229;r en &#8221;java.lang.OutOfMemoryError&#8221; har man et heap problem. Typisk vil applikationer blot standse helt eller delvist. Hvis man angiver for stor hukommelse vil det tager langt tid at k&#248;re GC og derved vil applikationen opleve &#8221;stop and go&#8221; funktionalitet med alvorlig forringelse i ydeevne. 

Applikationer med dynamisk kode og mange klasser som fx GEN, JSP, groovy osv kan blive n&#248;dt til at &#248;ge MaxPermSize. Den default JVM st&#248;rrelse for stakken er 64 megabyte. 

&lt;pre&gt;
-Xms512m
-Xmx1024m
-XX:MaxPermSize=128m
&lt;/pre&gt;

Hukommelsen gemmer objekter og stakken holder styr p&#229; oplysninger om objekter. Derfor, jo flere objekter, der findes, jo mere information finder der og jo st&#248;rre stak skal genneml&#248;bes ved hver GC. Efter denne logik fyldes Perm hurtigere hvis din applikation indeholder mange sm&#229; class-filer frem for f&#229; store class-filer. 


Hvordan sikre man at disse opstarts parameter rent faktisk virker? 

I Java 5.0 findes et omfattende overv&#229;gnings og ledelsesm&#230;ssig v&#230;rkt&#248;j. Jconsole er en gr&#230;nseflader indtil Java Virtual Machine men giver ogs&#229; out-of-the-box fjernbetjening, overv&#229;gning og forvaltning. Den bruger omfattende instrumentering af JVM for at give oplysninger om ressource forbrug af applikationer ved hj&#230;lp af Java Management Extension (JMX) teknologi.. 

Man kan lave sine egne beans til overv&#229;gning og styring af selvbyggede processer i JVM. En bean skal f&#248;lger og opfylde JMX design m&#248;nstre. En bean kan repr&#230;sentere et program eller en ressource som skal forvaltes. Intern i bean findes l&#230;se og skrive attributter samt metoder til invokation. En bean kan ogs&#229; udsende meddelelser ved at foruddefinerede begivenheder. 
Hvis man vil monitorere en remote proces i en JVM kan man tilf&#248;je disse &#8211;D parameter.  

&lt;pre&gt;
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=[port]
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
&lt;/pre&gt;

Derefter er at blot at starte Jconsole og connected under remote fanen.

Der findes en r&#230;kke parameter man kan overf&#248;re til JVM via -D argument. Men m&#229;ske m&#229; du ser realiteten i &#248;jne og erkende at din applikation har alvorlige fejl som b&#248;r l&#248;ses.   



* Xmx1500m # Heap size p&#229; 1500 MB
* Xincgc # Incremental low pause collector. L&#248;bende oprydning af tenured space.
* XX:GCTimeRatio=24  # lad JVM selv bestemme sit footprint ud fra en m&#229;ls&#230;tning om at bruge 4% af tiden p&#229; GC
* Xmn1g # newsize p&#229; 1GB, svarer til ratio p&#229; 2/3 p&#229; jespers server (?)
* Xss128k # reducerer st&#248;rrelsen af stakken ifht. det vi k&#248;rer med nu mhp. at skabe mere plads til hoben.
* XX:+UseConcMarkSweepGC  # Concurrent mark sweep collector
* XX:SurvivorRatio=10  # Survivor space 1:10
* XX:TargetSurvivorRatio=90 # Bedre pladsudnyttelse af survivor space
* XX:MaxTenuringTreshold=15 # Objekter kan overleve flere sweeps f&#248;rend de bliver flyttet til tenured


</body>
    <category-id type="integer" nil="true"></category-id>
    <created-at type="datetime">2008-10-14T03:32:26Z</created-at>
    <id type="integer">123</id>
    <post-id type="NilClass">123</post-id>
    <published type="boolean">true</published>
    <tag-id type="NilClass">30</tag-id>
    <title>Java Virtual Machine Heap Memory</title>
    <updated-at type="datetime">2008-10-22T22:32:12Z</updated-at>
  </post>
  <post>
    <body>I disse gr&#248;nne milj&#248; tider m&#229; man som udvikler t&#230;nke p&#229; mange ting. Denne gang vil jeg f&#248;rst og fremmest t&#230;nke p&#229; str&#248;mforbrug og etiske regels&#230;t n&#229;r man konstruere og drifter systemer. Det ville v&#230;re fedt at have sm&#229; super hurtige systemer som kan fungere ved at minimalt energiforbrug. Jeg har i mange &#229;r haft mine egen dedikeret serverer men i lange tider st&#229;r de faktisk n&#230;sten ubenyttet hen. 

Nu beh&#248;ver jeg ikke et top moderen drift center til mine sm&#229; webapplikationer og EDI udveksling men jeg har alligevel sat et par m&#229;l. 

* Hardwaren m&#229; ikke bruge mere en 10 Watt. 
* Hardwaren m&#229; ikke v&#230;re h&#248;rbar p&#229; en meter. 
* Inge service m&#229; tage mere end et halvt sekund. 

Normalt vil de fleste bare have maksimal hastighed men det er faktisk ikke s&#230;rligt sjovt, og det forbruger en masse str&#248;m og udvikler dermed ogs&#229; en masse varme. Jeg har fx en Dell Laptop der bliver s&#229; varm at jeg ikke kan se film og samtidig ha den p&#229; l&#229;rene. 

Ved at g&#229; lidt ned i CPU hastighed og i stedet indf&#248;re multi-core chiplevel Multi Processor(CMP) kan man opn&#229;r en betragtelig udnyttelsesgrad men n&#230;sten ingen &#248;gning i str&#248;mforbrug. 

Nu er det selvf&#248;lgelig s&#229;dan at n&#230;sten ingen applikationer kan udnytte flere CPU kerner til fulde. Fx kan man se en Java proces udnytte den ene proces 100% p&#229; en dual core maskine mens den anden st&#229;r ubenyttet i dvale.   

Jeg har k&#248;bt en linutop. Det er en lille box med superlavt str&#248;mforbrug og den er lydl&#248;s fordi der ikke er bev&#230;gelige dele i den. Reelt set er det kun et stykke printplade med nogle chips samlet i en aluminiums kasse. Den har ikke nogen harddisk eller andet som &#230;der str&#248;m eller skaber varme, kun CPU'en laver lidt varme. Boxen har en AMD Geode LX700 processor med 256 MB RAM og 4x USB 2.0 porter, audio og 10/100baseT Ethernet og VGA output. Den forbruger 5W.  

Der findes ikke et operativ i boxen men jeg vil have linux p&#229; den. Derfor har jeg prepereret en USB n&#248;gle med Mandriva, mit favorit linux styresystem gennem mange &#229;r. Mandiva kan installeres som fuld desktop eller server installation. 

&lt;a href=&quot;http://store.mandriva.com&quot;&gt;
&lt;img width=&quot;100&quot; src=&quot;http://store.mandriva.com/images/Mandriva-linutop2.jpg&quot;&gt;&lt;/a&gt;

N&#229;r Linutop&#8217;en modtager en bootable USB med et operativsystem starter den en lille fin distribution op med linux kernel 2.6.22.9-desktop586-1mdv med grafisk KDE 3.5 gr&#230;nseflade. USB'en k&#248;re perfekt p&#229; alle mine computere s&#229; l&#230;nge den bruger de respektive interne ressource men p&#229; linutop er problemet den lille AMD processor og de kun 256 MB RAM. 

Mandriva booter ikke default med sshd installeret og derudover er firewallen hermetisk lukket. Af gammel vane og for lidt ram skifter jeg ved samme lejlighed til et lavere runlevel i /etc/inittab, jeg har ikke brug for at logge grafisk ind over X. 

S&#229; er det ssh til boxen og installere noget software. Da softwaren er en fuldfed desktop udgave med 100vis af processer k&#248;rende og det tager lidt tid at finde alle de processer som jeg kan slukke uden det betyder noget for serveren. Her er resultatet, ca. 50 processer tilbage og lige over 60 MB fri mem. N&#229;r man ssh til boxen kan man fx starte drakconf, applikationen k&#248;re lynhurtige og kaster sit images p&#229; p&#229; den box hvor jeg er logget ind fra. 

&lt;pre&gt;
top - 01:45:20 up 45 min,  1 user,  load average: 0.00, 0.00, 0.07
Tasks:  52 total,   1 running,  51 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.3%us,  0.3%sy,  0.0%ni, 99.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    235792k total,   171112k used,    64680k free,    15904k buffers
Swap:        0k total,        0k used,        0k free,   131304k cached
&lt;/pre&gt;

S&#229; er min lydl&#248;se USB computer ved at v&#230;re parat til at f&#229; installeret software, jeg vil k&#248;re med ruby on rails, en webserver instans, en database og nogle kontrolstrukture til vedligehold og genstart af serverne. 

&lt;pre&gt;
frank@linutop www]# free -m
             total       used       free     shared    buffers     cached
Mem:           230        176         53          0         16        110
-/+ buffers/cache:         49        181
Swap:            0          0          0
&lt;/pre&gt;

N&#229;r det hele k&#248;re m&#229; det helst ikke fylder mere end ca. 40MB mem. Ruby er standard p&#229; mandiva men rubygems og ruby on rails er ikke. P&#229; samme m&#229;de skal der v&#230;lges en database. hmmm gerne en med lille footprint.   

Normalt ville jeg benytte Apaches httpd server som webserver men da RAM er lidt begr&#230;nset vil jeg udskifte den med noget andet. Ofte fylder et kald til en apache instans op til ca. 20MB og det ville hurtigt slukke serveren. Min andet bud p&#229; en webserver er lighttpd, den er kendt for et specielt lille foodprint. 

Mongrel er en hurtig HTTP server for Ruby som benytter ren HTTP fremfor FastCGI som de to andre bruger. Da alt software ligger p&#229; en USB n&#248;gle vil jeg gerne undg&#229; at compliere yderligere pakker som fx fcgi. 

Thin er en ret ny og ret upr&#248;vet webserver men da den er udviklet i ren ruby vil jeg alligevel fors&#248;ge mig med den. Den skulle v&#230;re endnu hurtigere end Mongrel men jeg har ogs&#229; erfaret at den mister en tr&#229;d en gang i mellem. Det betyder at operativsystemet fanger en tr&#229;d som bruger en 10 til 15 procent af CPU&#8217;en. Efter 1 min bliver den piggybacked. Mongrel serveren bruger ca. 25 til 40MB i min opstilling her og det overrasker mig en smule at Thin bruger lidt mere. Om den i virkeligheden er hurtigere ved jeg ikke. 

Som database v&#230;gler jeg Sqlite. Rails 2 v&#230;lger den som default og jeg er med p&#229; noget nyt, eneste rigtige showstopper med sqlite er for mange clienter til samme database men det er ikke et problem her. 

Migrate af data fra mine gamle databaser til sqlite bliver ogs&#229; h&#229;ndteret af ruby. Se post Mutible ActiveRecord. Som det ses er databasen p&#229; lige over 3 GB. Lidt sejt n&#229;r der ogs&#229; er et linux system p&#229; flash n&#248;glen. 

&lt;pre&gt;
[frank@linutop db]$ ll -h
total 332K
-rw-r--r-- 1 frank frank  10K 2007-01-25 01:09 dev.sqlite3
drwxr-xr-x 2 frank frank 4.0K 2008-01-02 23:04 migrate/
-rw-r--r-- 1 frank frank 3,6G 2008-01-04 15:04 production.sqlite3
-rw-r--r-- 1 frank frank 1.6K 2008-01-03 14:56 schema.rb
&lt;/pre&gt;

S&#229; er det tid til at starte hele dynen. Jeg har lavet nogle scrips til start og stop af serveren og sat cron til at checke om den k&#248;re og hvis ikke starte den. I f&#248;rste omgang vil jeg bare k&#248;re en enkelt instans men det ser ud til jeg kan k&#248;re flere hvis det beh&#248;ves. Underligt nok fylder en enkelt instans ca. 35 MB mens to fylder kun lidt mere? 

Ulempen er hastigheden grunden den relativt lille m&#230;nge RAM. Stabiliteten har indtil videre v&#230;re utrolig h&#248;j. Her er en k&#248;rsel efter n&#230;sten 4 d&#248;gn. Man kan se kthreadd har v&#230;re aktiv, nok en tabt tr&#229;d fra Thin. Thin serveren bruger 33M og ser aktiv ud. 
&lt;pre&gt;
top - 21:54:36 up 9 days,  2:16,  1 user,  load average: 0.12, 0.04, 0.01
Tasks:  57 total,   1 running,  55 sleeping,   1 stopped,   0 zombie
Cpu(s):  0.0%us,  0.3%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    235792k total,   231660k used,     4132k free,    22328k buffers
Swap:        0k total,        0k used,        0k free,   133180k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND           
    1 root      20   0  1652  564  492 S  0.3  0.2   0:16.59 init               
10899 root      20   0 42596  37m 3088 S  0.3 16.3  89:30.20 thin               
11576 frank     20   0  2160  972  796 R  0.3  0.4   0:00.09 top                
    2 root      15  -5     0    0    0 S  0.0  0.0   0:00.01 kthreadd           
    3 root      RT  -5     0    0    0 S  0.0  0.0   0:00.00 migration/0        
    4 root      15  -5     0    0    0 S  0.0  0.0   0:01.61 ksoftirqd/0     
&lt;/pre&gt;

h5. Update 

&lt;pre&gt;
top - 18:46:21 up 43 days, 23:07,  1 user,  load average: 0.06, 0.06, 0.01
Tasks:  57 total,   1 running,  55 sleeping,   1 stopped,   0 zombie
Cpu(s):  0.3%us,  0.7%sy,  0.0%ni, 99.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    235792k total,   231824k used,     3968k free,    16220k buffers
Swap:        0k total,        0k used,        0k free,   117904k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND           
17282 frank     20   0  2160  976  796 R  0.7  0.4   0:01.71 top                
12344 root      20   0 56464  51m 3092 S  0.3 22.2 713:56.60 thin               
    1 root      20   0  1652  564  492 S  0.0  0.2   1:06.82 init               
    2 root      15  -5     0    0    0 S  0.0  0.0   0:00.01 kthreadd           
    3 root      RT  -5     0    0    0 S  0.0  0.0   0:00.00 migration/0        
    4 root      15  -5     0    0    0 S  0.0  0.0   0:02.68 ksoftirqd/0        
    5 root      15  -5     0    0    0 S  0.0  0.0   2:54.08 events/0           
    6 root      15  -5     0    0    0 S  0.0  0.0   0:00.04 khelper            
   29 root      15  -5     0    0    0 S  0.0  0.0   0:00.82 kblockd/0          
   30 root      15  -5     0    0    0 S  0.0  0.0   0:00.05 kseriod            
&lt;/pre&gt;

Hvis du kan l&#230;se denne blog k&#248;re min linutop :-) Fascinerede lydl&#248;st    


&quot;Linutop&quot;:http://linutop.com/
&quot;Mandriva store&quot;:http://store.mandriva.com/
</body>
    <category-id type="integer">6</category-id>
    <created-at type="datetime">2008-01-09T22:18:00Z</created-at>
    <id type="integer">90</id>
    <post-id type="NilClass">90</post-id>
    <published type="boolean">false</published>
    <tag-id type="NilClass">30</tag-id>
    <title>Green Rails</title>
    <updated-at type="datetime">2008-03-10T01:40:50Z</updated-at>
  </post>
  <post>
    <body>Hvad er en entreprise service bus og hvad skal en ESB g&#248;re?

Heldigvis findes ingen konkret industri definition p&#229; en ESB. Nogle definere en ESB som v&#230;rende en arkitektur komponent, andre definere ESB med udgangspunkt i hardware platforme og andre igen definere ESB som arkitektoniske m&#248;nstre. 

ESB definitionen betyder forskellige ting for forskellige mennesker desv&#230;rre. 

Hvis man s&#248;ger informationer om ESB gennem brochure, p&#229; web eller hos udbyder af l&#248;sninger f&#229;r man endnu flere forskellige rettede oplysninger. Reklamerne er fulde af buswords som workflow, BPEL server og applikation extensions osv osv.  

Sv&#230;rt at forst&#229; hvad det i virkeligheden er og mange bruge masser af tid p&#229; at pr&#248;ve at forst&#229;r Man kan vende det lidt p&#229; hoved og pr&#248;ve at definere en bus udefra hvilken egenskaber den udfylder og hvad som skal erstatte den ifald den fjernes. 

ESB er en implementering af SOX som er en eksekverings kontekst. Med andre ord, i SOA har vi en klient som er en forbruger af services og vi har en server som er en udbyder af services. ESB har til hoved opgave at forbinde de to p&#229; den mest simple m&#229;de, hurtigt og let. Ud fra et definitions standpunkt passer ESB&#8217;en perfekt. 

Hvor kan man med fordel bruge en ESB og hvorn&#229;r skal man ikke? Et godt eksempel er n&#229;r der findes flere delte services p&#229; flere klient applikationer. Dette er et typisk SOA scenario hvor en ESB performere virkeligt godt. Et d&#229;rligt eksempel er en single silo applikation med f&#229; dedikeret services. 

Skal man have et ESB produkt for at implementere en SOA applikation? Det er et trick sp&#248;rgsm&#229;l. Nej. Der er tre ting man kan bruge i stede, en hardware plan, en software produkt eller man kan bruge et m&#248;nster men det som er pointen her er at n&#229;r vi implementere SOA der er bestemte egenskaber som skal v&#230;re til stede som fx ruting, besked udveksling, besked transformation, besked protokol, osv. Disse egenskaber skal v&#230;re et sted i en SOA applikation og forh&#229;bentlig er det ikke klientens ansvar, heller ikke sevices, og heller ikke middelware. S&#229; svaret er stadig nej, men s&#229; m&#229; man selv implementere de egenskaber som en ESB l&#248;ser.  

ESB implementere ikke direkte en service orienteret arkitektur (SOA) men tilbyder svar p&#229; mange forskellige l&#248;sninger. Det er en f&#230;lles overbevisning at en ESB kun er til web services men der kan benyttes mange protokoller. ESB b&#248;r v&#230;re standart baseret, fleksible og supportere mange transport media. Baseret p&#229; EAI frem for SOA m&#248;nstre pr&#248;ver det at fjerne den t&#230;tte kobling mellem service kalder og selve transport medium. 
Er der nogen ting som man kan undv&#230;re i en ESB? Hvis man kigger p&#229; en ESB som en arkitektur komponent ud fra et objekt orienteret synsvinkel er der klart egenskaber som procenterne smider med I pakken som ikke n&#248;dvendigvis tilh&#248;rer en effektiv messing bus. 

Analogi til Java sproget. Vi taler ikke mere om Java som sprog men mere som en platform. Vi inddrage en masse komponenter under det samme ord. Og s&#229;dan er det ogs&#229; med en ESB. En ESB som komponent b&#248;r hurtig, let og funger som middelware messing bus men vi begynder at fylde mere og mere adf&#230;rd p&#229; den, nogle gange er det n&#248;dvendigt og andre gange er det bare flof. 

Ting som efter min mening ikke h&#248;rer hjemme i en ESB er fx process choreography, services orchestration og meget andet gejl. 

M&#229;ske mangler der en r&#229; super hurtig beskeds bus som kan binde klienter og server samme. </body>
    <category-id type="integer">6</category-id>
    <created-at type="datetime">2007-03-21T09:08:00Z</created-at>
    <id type="integer">29</id>
    <post-id type="NilClass">29</post-id>
    <published type="boolean">false</published>
    <tag-id type="NilClass">30</tag-id>
    <title>Enterprise service bus(ESB)</title>
    <updated-at type="datetime">2008-04-08T07:17:32Z</updated-at>
  </post>
  <post>
    <body>The single biggest hardware issue affecting web server performance is RAM. A webserver should never ever have to swap memory! Swapping increases the latency of each request beyond a point that users consider &quot;fast enough&quot;. This causes users to hit stop and reload, further increasing the load. You can, and should, control the MaxClients setting so that your server does not spawn so many children it starts swapping. 
The procedure is simple: determine the size of your average Apache process, by looking at your process list via a tool such as top, and divide this into your total available memory, leaving some room for other processes.
This issue becomes major when you realize that after each process has done its job, the bloated process sits and spoon-feeds data to the client, instead of moving on to bigger and better things. This problem is compounded by a bit of essential info that should really be more common knowledge:
If you serve 100% static files with Apache, each httpd process will use around 2-3 megs of RAM.
If you serve 99% static files and 1% dynamic files with Apache, each httpd process will use from 3-20 megs of RAM (depending on your MOST complex dynamic page).
This occurs because a process grows to accommodate whatever it is serving, and NEVER decreases until that process dies. Unless you have very few dynamic pages and major traffic fluctuation, most of your httpd processes will soon take up an amount of RAM equal to the largest dynamic script on your system. A very smart web server would deal with this automatically. As it is, you have a few options to manually improve RAM usage.
Beyond that the rest is mundane: get a fast enough CPU, a fast enough network card, and fast enough disks, where &quot;fast enough&quot; is something that needs to be determined by experimentation.</body>
    <category-id type="integer">6</category-id>
    <created-at type="datetime">2007-01-27T00:40:00Z</created-at>
    <id type="integer">2</id>
    <post-id type="NilClass">2</post-id>
    <published type="boolean">false</published>
    <tag-id type="NilClass">30</tag-id>
    <title>Apache RAM</title>
    <updated-at type="datetime">2008-08-20T09:30:04Z</updated-at>
  </post>
</posts>
