|
| java garbagecollection på Linux Fra : Søren Boll Overgaard |
Dato : 11-03-02 18:29 |
|
Hej
Jeg sidder og undrer mig en del over om det er mig der har lavet en fejl,
eller om det er javas garbagecollector der er underlig på Linux.
Jeg har lavet et lille program der starter X tråde der hver især laver
(mange) navneopslag, og skriver resultaterne ud.
Koden ser ud som sådan:
---8<---
import java.net.*;
public class Resolver extends Thread {
LookupController source;
String name;
public Resolver(LookupController lc, String name) {
source = lc;
this.name = name;
}
public void run() {
String hostname;
InetAddress ip;
while (true) {
hostname = source.getNextIp();
if (hostname!=null) {
try {
ip = InetAddress.getByName(hostname);
hostname = ip.getHostName();
System.out.println(ip);
} catch (Exception e) {
//System.out.println(name+": Unable to resolve "+hostname);
}
}
}
}
}
---8<---
Hver process starter med at fylde i omegnen af 6 MB i hukommelsen,
hvilket sådan set er fint nok.
Imidlertid fylder de hver, efter ca. 1 times kørsel, ca. 15 MB i
hukommelsen. Ved 100 paralelle processer bliver det jo en del ekstra
hukommelse der skal allokeres til java.
Som default tillader jvm på Linux kun allokering af 64 MB til sig selv,
hvorfor der ikke går ret længe inden programmet springer i luften og
exiter med en "out of memory error".
Er der nogen måde hvorpå man man tweake garbage collectoren så den enten
er mere aggressiv, eller mere effektiv, måske på bekostning af noget
performance?
--
Søren Boll Overgaard
| |
Thorbjørn Ravn Ander~ (11-03-2002)
| Kommentar Fra : Thorbjørn Ravn Ander~ |
Dato : 11-03-02 19:25 |
|
Søren Boll Overgaard <harvest@wheel.dk> writes:
> hostname = source.getNextIp();
> Hver process starter med at fylde i omegnen af 6 MB i hukommelsen,
> hvilket sådan set er fint nok.
> Imidlertid fylder de hver, efter ca. 1 times kørsel, ca. 15 MB i
> hukommelsen. Ved 100 paralelle processer bliver det jo en del ekstra
> hukommelse der skal allokeres til java.
Faar du nulstillet alle dine referencer til objekter der ikke skal
bruges mere? Det ser ud som om du har en haegtet liste, og hvis der
bare er een reference til starten, saa har du hele listen altid i
hukommelsen.
--
Thorbjørn Ravn Andersen
http://homepage.mac.com/ravn
| |
Søren Boll Overgaard (11-03-2002)
| Kommentar Fra : Søren Boll Overgaard |
Dato : 11-03-02 19:58 |
|
On Mon, 11 Mar 2002 19:25:06 +0100, Thorbjørn Ravn Andersen wrote:
> Søren Boll Overgaard <harvest@wheel.dk> writes:
>
>> hostname = source.getNextIp();
>
>> Hver process starter med at fylde i omegnen af 6 MB i hukommelsen,
>> hvilket sådan set er fint nok.
>> Imidlertid fylder de hver, efter ca. 1 times kørsel, ca. 15 MB i
>> hukommelsen. Ved 100 paralelle processer bliver det jo en del ekstra
>> hukommelse der skal allokeres til java.
>
> Faar du nulstillet alle dine referencer til objekter der ikke skal
> bruges mere? Det ser ud som om du har en haegtet liste, og hvis der
> bare er een reference til starten, saa har du hele listen altid i
> hukommelsen.
Hvor mener du der skulle være en linket liste?
Jeg har med vilje puttet hostname og ip udenfor while()-løkken for at
undgå at der laves nye instanser ved hver iteration, så jeg skulle ikke
mene at det er det der udgør problemet?
Jeg er godt klar over at hvis der bare een reference til et objekt
forbliver det i hukommelsen, ellers ville garbage collection jo være
temmlig destruktivt :)
--
Søren Boll Overgaard
| |
Ulrik Magnusson (11-03-2002)
| Kommentar Fra : Ulrik Magnusson |
Dato : 11-03-02 20:34 |
|
Søren Boll Overgaard wrote:
> On Mon, 11 Mar 2002 19:25:06 +0100, Thorbjørn Ravn Andersen wrote:
>
> > Søren Boll Overgaard <harvest@wheel.dk> writes:
> >
> >> hostname = source.getNextIp();
> >
> >> Hver process starter med at fylde i omegnen af 6 MB i hukommelsen,
> >> hvilket sådan set er fint nok.
> >> Imidlertid fylder de hver, efter ca. 1 times kørsel, ca. 15 MB i
> >> hukommelsen. Ved 100 paralelle processer bliver det jo en del ekstra
> >> hukommelse der skal allokeres til java.
> >
> > Faar du nulstillet alle dine referencer til objekter der ikke skal
> > bruges mere? Det ser ud som om du har en haegtet liste, og hvis der
> > bare er een reference til starten, saa har du hele listen altid i
> > hukommelsen.
>
> Hvor mener du der skulle være en linket liste?
> Jeg har med vilje puttet hostname og ip udenfor while()-løkken for at
> undgå at der laves nye instanser ved hver iteration, så jeg skulle ikke
> mene at det er det der udgør problemet?
>
Det gøres der ikke alligevel:
while( true )
{
String s = "";
}
er præcis det samme som
String s;
while( true )
{
s = "";
}
Erklæringer koster ikke noget, men er udelukkende til for
at gennemtvinge typesystemet. Det er nok anbefalelsesværdigt
kun at bruge konstruktion nummer 2, når "s" skal bruges efter
løkken (det er i hvert fald signalet du sender til andre læsere
af koden).
Ulrik Magnusson
| |
Thorbjørn Ravn Ander~ (11-03-2002)
| Kommentar Fra : Thorbjørn Ravn Ander~ |
Dato : 11-03-02 20:46 |
|
Ulrik Magnusson <ulrikm@yahoo.com> writes:
> > Hvor mener du der skulle være en linket liste?
Hvordan er getNextSourceId() implementeret? (Eller hvad den nu hed).
--
Thorbjørn Ravn Andersen
http://homepage.mac.com/ravn
| |
Ulrik Magnusson (11-03-2002)
| Kommentar Fra : Ulrik Magnusson |
Dato : 11-03-02 20:42 |
|
"Thorbjørn Ravn Andersen" wrote:
> Ulrik Magnusson <ulrikm@yahoo.com> writes:
> > > Hvor mener du der skulle være en linket liste?
> Hvordan er getNextSourceId() implementeret? (Eller hvad den nu hed).
Det er sgu et godt spørgsmål
Ulrik Magnusson
| |
Søren Boll Overgaard (11-03-2002)
| Kommentar Fra : Søren Boll Overgaard |
Dato : 11-03-02 20:58 |
|
On Mon, 11 Mar 2002 20:45:46 +0100, Thorbjørn Ravn Andersen wrote:
> Ulrik Magnusson <ulrikm@yahoo.com> writes:
>
>> > Hvor mener du der skulle være en linket liste?
>
> Hvordan er getNextSourceId() implementeret? (Eller hvad den nu hed).
>
Noget i den her stil:
public synchronized String getNextIp() {
if (first==255 && second== 255 && third==255 && fourth==255) {
return null;
}
fourth = fourth+1;
if (fourth==256) {
fourth=0;
third = (third+1)%256;
}
if (third==0 && fourth==0) {
second = (second+1)%256;
}
if (second==0 && third==0 && fourth==0) {
first = (first+1)%256;
}
return fourth+"."+third+"."+second+"."+first+".tld";
}
Indrømmet, det er lidt noget hamsterkode, men det skulle virke.
--
Søren Boll Overgaard
| |
Rasmus W (13-03-2002)
| Kommentar Fra : Rasmus W |
Dato : 13-03-02 18:06 |
|
Søren Boll Overgaard wrote:
> Hej
>
> Jeg sidder og undrer mig en del over om det er mig der har lavet en fejl,
> eller om det er javas garbagecollector der er underlig på Linux.
> Jeg har lavet et lille program der starter X tråde der hver især laver
> (mange) navneopslag, og skriver resultaterne ud.
> Koden ser ud som sådan:
>
<Klip: koden>
Garbage collector tråden har ret lav prioritet. Det ser ikke ud som om
du giver den lov til at eksekvere.
Hvis du kalder Thread.sleep(delay) f.eks. efter System.out.println(ip),
så får garbage collectoren sandsynligvis lov til at eksekvere en gang
imellem.
Mvh Rasmus
| |
Soren 'Disky' Reinke (13-03-2002)
| Kommentar Fra : Soren 'Disky' Reinke |
Dato : 13-03-02 21:12 |
|
"Rasmus W"
<if.you.really.want.to.reply.by.mail.then.do.it.to.rwatjen@hotmail.com>
wrote in message news:3C8F8708.3060202@hotmail.com...
> Søren Boll Overgaard wrote:
>
> > Hej
> >
> > Jeg sidder og undrer mig en del over om det er mig der har lavet en
fejl,
> > eller om det er javas garbagecollector der er underlig på Linux.
> > Jeg har lavet et lille program der starter X tråde der hver især laver
> > (mange) navneopslag, og skriver resultaterne ud.
> > Koden ser ud som sådan:
> >
> <Klip: koden>
>
> Garbage collector tråden har ret lav prioritet. Det ser ikke ud som om
> du giver den lov til at eksekvere.
> Hvis du kalder Thread.sleep(delay) f.eks. efter System.out.println(ip),
> så får garbage collectoren sandsynligvis lov til at eksekvere en gang
> imellem.
Den har lav prioritet ja, men hvis der mangler ram så overtager den bare og
laver en fuld GC som godt kan tage sekunder.
--
With many Thanks
Soren ' Disky ' Reinke ICQ #1413069 remove 'ihsyd' when email replying
Please visit my Freshwater Aquaria Webpage
http://www.disky-design.dk/fish
| |
Thorbjørn Ravn Ander~ (13-03-2002)
| Kommentar Fra : Thorbjørn Ravn Ander~ |
Dato : 13-03-02 21:35 |
|
"Soren 'Disky' Reinke" <disky@disky-design.ihsyd.dk> writes:
> Den har lav prioritet ja, men hvis der mangler ram så overtager den bare og
> laver en fuld GC som godt kan tage sekunder.
Det gjalt i gamle dage. GC i HotSpot er optimeret meget, og fungerer
meget mindre paafaldende.
--
Thorbjørn Ravn Andersen
http://homepage.mac.com/ravn
| |
Soren 'Disky' Reinke (13-03-2002)
| Kommentar Fra : Soren 'Disky' Reinke |
Dato : 13-03-02 23:07 |
|
>
> > Den har lav prioritet ja, men hvis der mangler ram så overtager den bare
og
> > laver en fuld GC som godt kan tage sekunder.
>
> Det gjalt i gamle dage. GC i HotSpot er optimeret meget, og fungerer
> meget mindre paafaldende.
Det er korrekt det går langt bedre nu.
Men det tager stadigvæk lang tid hvis den virkeligt skal ryde op, så
eksempler på Javaone sidste år, med tests af netop hotspol med -server
parameter der bliver monster belastet og havde for lidt ram, tiderne var op
til 1.5 sekunder. (han sagde dog at de var fremtvunget med vilje, og ikke
virkeligheds tro.)
Men jdk 1.4 er MEGET bedre end f.eks. jdk 1.8.1 til GC
--
With many Thanks
Soren ' Disky ' Reinke ICQ #1413069 remove 'ihsyd' when email replying
Please visit my Freshwater Aquaria Webpage
http://www.disky-design.dk/fish
| |
Søren Boll Overgaard (14-03-2002)
| Kommentar Fra : Søren Boll Overgaard |
Dato : 14-03-02 10:33 |
|
On Wed, 13 Mar 2002 18:06:16 +0100, Rasmus W wrote:
> Søren Boll Overgaard wrote:
>
> > Hej
> >
> > Jeg sidder og undrer mig en del over om det er mig der har lavet en
> > fejl, eller om det er javas garbagecollector der er underlig på
> > Linux. Jeg har lavet et lille program der starter X tråde der hver
> > især laver (mange) navneopslag, og skriver resultaterne ud. Koden ser
> > ud som sådan:
> >
> <Klip: koden>
>
> Garbage collector tråden har ret lav prioritet. Det ser ikke ud som om
> du giver den lov til at eksekvere.
Jep, man kan vel godt kalde den while (true) for et ret tight loop.
> Hvis du kalder Thread.sleep(delay) f.eks. efter System.out.println(ip),
> så får garbage collectoren sandsynligvis lov til at eksekvere en gang
> imellem.
Er System.gc() ikke snedigere at bruge i den henseende?
--
Søren Boll Overgaard
| |
Rasmus W (14-03-2002)
| Kommentar Fra : Rasmus W |
Dato : 14-03-02 15:05 |
|
Søren Boll Overgaard wrote:
>> Hvis du kalder Thread.sleep(delay) f.eks. efter System.out.println(ip),
>> så får garbage collectoren sandsynligvis lov til at eksekvere en gang
>> imellem.
>
> Er System.gc() ikke snedigere at bruge i den henseende?
>
Nej, ikke rigtigt. Med System.gc() beder du bare garbage collectoren om at
køre. Du kan ikke tvinge den til det.
Dvs. med System.gc() siger du: "Please, please. Could you please run the
garbage collector, when you have a spare moment." - JVMen snakker
naturligvis kun engelsk
Jeg vil næsten tro at Thread.sleep(1) er nok, da det vil bringe din tråd ud
af processoren og tilbage i køen, men 10 er nok bedre. Og det værste der
kan ske er at en anden af dine tråde får lov til at køre.
Mvh Rasmus
| |
|
|