[JAVA] vergroten 'java stack'

Pagina: 1
Acties:

  • bille
  • Registratie: Mei 2000
  • Laatst online: 05-08 23:45

bille

Don't call me Buff

Topicstarter
Ik heb laatst een programmatje gemaakt waarin bepaalde functies recursief worden aangeroepen. Echter naar een aantal iteratie dan krijg ik een java.lang.StackOverflowError. Door in de JAVA api te kijken zag ik dat het inderdaad kwam door de recursie in mijn app. Alleen nu wil ik wel graag dat mijn applicatie verder wordt afgelopen zonder die StackOverflowError. Ben ik gaan zoeken en kwam erachter dat er een argument bestaat om de stack mee te vergroten namelijk: JAVA.exe [argumenten] -Xss (size)

alleen als ik dat ingeef bij de VM parameters dan krijg ik de melding dat de VM niet gestart kan worden.. en ik heb geen id waar dat aan kan liggen. Kan wel gewoon mijn applicatie starten zonder die optie, maar dan krijg ik dus de StackOverflowError. Misschien dat het aan de waarde ligt die ik meegeef :? ik heb al van 32MB tot 32000000 geprobeerd... maar krijg iedere keer dezelfde melding terug :(

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik weet niet hoeveel stack er standaard beschikbaar is, maar je moet toch een behoorlijk aantal recursieve aanroepen doen voordat je stack op is. Ik weet verder niet wat je nivo is op het gebied van proggen, maar als je nog een beginner bent: weet je zeker dat je niet een fout erin hebt zitten?

[edit]
probeer eens zonder mb erachter. Dus 32 of 64.

[ Voor 10% gewijzigd door Alarmnummer op 27-11-2002 19:49 ]


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
In je VM kan je zien hoe veel geheugen er gealloceerd en hoeveel er daarvan gebruikt is. Ik heb eerder het idee dat de stack wel verhoogd is, maar dat hij gewoon nog steeds volloopt.

Wat roep je eigenlijk recursief aan? Stopt de boel wel :?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Je kan ook je recursieve functie herschrijven naar een niet recursief stukje code. Dit is theoretisch mogelijk met elke recursie. Het voordeel is ook dat het vaak veel sneller wordt, want recursie is relatief langzaam. Het grote nadeel is alleen dat het vaak minder logisch werkt en veel ingewikkelder wordt.

We adore chaos because we like to restore order - M.C. Escher


  • MisterData
  • Registratie: September 2001
  • Laatst online: 26-08 21:52
Post anders eens wat code?

  • bille
  • Registratie: Mei 2000
  • Laatst online: 05-08 23:45

bille

Don't call me Buff

Topicstarter
hmm ok .. stukje code dan maar..

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public double[][] retrieveNextDataset() throws IndexOutOfBoundsException{
        increase();
        return shares;
    }
    private void increase() throws IndexOutOfBoundsException{
        boolean increaseFlag = false;
        count++;
        shares[countryIndex][supplierIndex]+=stepSize;
        if(shares[countryIndex][supplierIndex] <= localRestrictions[countryIndex][supplierIndex].max) {
            countryIndex =countries-1;
            supplierIndex = suppliers-1;
        } else {
            shares[countryIndex][supplierIndex] = localRestrictions[countryIndex][supplierIndex].min;
            supplierIndex-=1;
            if(supplierIndex<0) {
                countryIndex-=1;
                if(countryIndex<0) {
                    System.out.println("Alle landen afgelopen..");
                    System.out.println("Aantal increases:"+count);
                    throw new IndexOutOfBoundsException ("Alle landen afgelopen");
                }
                supplierIndex = suppliers-1;
            }
            increaseFlag = true;
        }
        if(!isValidDatasetIntRestrictions () || increaseFlag){
            increase();
        }
    }
    private boolean isValidDatasetIntRestrictions(){
        double targetSOBGPS = 0; // target avg share of business 'group prefered suppliers'
        for(int i=0; i<= countries-1; i++){
            targetSOBGPS = internationalRestrictions[i];
            for(int z=0; z<= suppliers-1; z++){
                targetSOBGPS-= shares[i][z];
            }
            if(targetSOBGPS <-0.02 || targetSOBGPS>0.02 ){
                return false;
            }
        }
        return true;
    }


Ok wat je hierboven ziet zal wel vrij wazig lijken.. Er zit toch een verband in :)
deze code zit in een object dat een datasetfactory moet voorstellen. Één dataset is een 2 dimensionale array met per dimensie 3 variabelen (type= double). Met die dataset voer ik een bepaalde berekening uit. De formule achter de berekening zit zo in elkaar dat het bepalen van een maximum alleen gedaan kan worden doormiddel van het doorrekenen van alle mogelijke waardes voor de variabelen in de formule. Álle mogelijke waardes is eigelijk niet helemaal waar, want de variabelen zijn nog wel gebonden aan bepaalde constraints.

Vanwege de complexiteit van de formule wil ik niet dat alle combinaties van variabelen geprobeerd worden, deze filter ik er dus van te voren uit. En dat is wat je ziet in de bovenstaande code.

De functie: "retrieveNextDataset()" wordt uitgevoerd binnen een loopje.. binnen datzelfde loopje wordt de returnwaarde van de functie gebruikt in de formule om de uitkomst te bepalen en te kijken of de uitkomst hoger is dan alle voorgaande uitkomsten.

De dataset waar ik het net over had bestaatd dus feitelijk uit 9 variabelen. Deze variabelen kunnen een waarde hebben tussen localRestrictions[countryIndex][supplierIndex].min en localRestrictions[countryIndex][supplierIndex].max. Gezien ik toch een heel aantal mogelijke combinaties wil laten doorrekenen begin ik daarom bij ieder van de 9 variabelen bij de .min waarde. Van daaruit laat ik de waarde ophogen met waarde
'stepSize'. Iedere keer als de functie increase() wordt aangeroepen wordt 1 van de variabelen in de 2 dimensionale array dus opgehoogt. Hoe dat gebeurd is met een soort bufferoverflow systeem.

ik heb dat gedaan door het alsvolgt te bekijken: er zijn in de 2 dimensionale array feitelijk 2 verschillende indexes. Iedere keer als 1 van de variabelen waar de 'supplierIndex' naar wijst over zijn '.max' waarde heen gaat dan wordt de supplierindex met verlaagt en wordt de volgende variabele 1 verhoogt. Dit gaat zo in loopje.

Er zijn echter nog meer constraints, namelijk: internationalRestrictions[].. per dimensie in de dataset mag de som van de 3 doubles shares[i] niet verder afwijken dan van -0.02 tot 0.02 van de waarde waar internationalRestrictions[i] voor staat.

de functie:
Java:
1
public double[][] retrieveNextDataset() throws IndexOutOfBoundsException
mag dus alleen iets terug geven wat een geldige dataset is volgens de localRestrictions[i][z] als de internationalRestrictions[i]. Om die reden heb ik de functie increase() recursief gemaakt. Hij roept net zovaak zichzelf aan tot hij een geldige dataset tegen komt en die wordt gereturned. Het zichzelf aanroepen gebeurd op basis van 2 argumenten:
Java:
1
2
3
if(!isValidDatasetIntRestrictions () || increaseFlag){
            increase();
        }


de increaseFlag wordt dus gezet opbasis van de check of de huidige dataset waarden binnen hun .min en .max waarde vallen en de functie isValidDatasetIntRestrictions () controleerd of de de som van de variabelen van de eerste dimensie in de shares array maximaal een afwijking heeft van -0.02 tot 0.02.

overgens zijn de waarden in shares[countryindex][supplierindex] doubles met waarden tussen 0.01 en 1, hetgeen voorstelt: van 1% tot 100%, maar procenten rekenen zo lastig ;)

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


  • bille
  • Registratie: Mei 2000
  • Laatst online: 05-08 23:45

bille

Don't call me Buff

Topicstarter
voor de mensen die handig zijn met UML:
hier klikken voor sequence diagram

[ Voor 35% gewijzigd door bille op 28-11-2002 02:00 ]

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


  • bille
  • Registratie: Mei 2000
  • Laatst online: 05-08 23:45

bille

Don't call me Buff

Topicstarter
maar goed tis misschien wel interessant maar ook wel offtopic :D eigelijk was ik opzoek naar een manier om de stack te vergroten :)

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

hint: er is een edit knop ;)

32 MB voor een programstack is heel erg veel, al helemaal voor een taal die alleen primitieven erop kan zetten (alle objecten worden op de heap gealloceerd). Even een hypothetisch voorbeeld:

stel dat een functieaanroep op zich 8 bytes van de stack in beslag neemt, en dat ie 4 parameters heeft van 8 byte per stuk. Dan komt er nog wat destruction en exception code op van laten we zeggen 32 bytes, en hij gebruikt ook nog 16 ints, floats en pointers aan lokale variabelen (elk 4 byte per stuk)

Dan is de stack frame van 1 functie: 8 + 4 * 8 + 32 + 16 * 4 = 136 byte. Maken we daar even 128 van, dat rekent wat makkelijker ;)
32 MB = 225
128 = 27

De functie kan zichzelf dus 225 / 27 = 218 keer aanroepen, dat is 262144 keer

Dat is erg veel voor een recursieve functie, die over het algemeen een orde O(log n) algoritme implementeren :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Je moet inderdaad wel vrij raar bezig zijn als je een stack-overflow krijgt en je zeker weet dat je recursieve methode altijd termineert. Ik zou dat laatste maar eens goed nakijken. Het is vrij eenvoudig na te gaan of dit het probleem is.

Het is echter niet onmogelijk ;) . Ik heb ooit eens wat experimenten met het Visitor pattern gedaan. Het bleek dat je hierbij door het aantal 'accept' aanroepen extreem snel een stack overflow krijgt. De getallen kan je hier nalezen als je het leuk vindt.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
In de tools documentatio kan je trouwens nagaan hoe je die sizes op moet geven:

http://java.sun.com/j2se/1.4.1/docs/tooldocs/linux/java.html

Het werkt volgens mij gewoon: dit werkt bijvoorbeeld voor een kleine test:

java -Xss3000000 Validate

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • bille
  • Registratie: Mei 2000
  • Laatst online: 05-08 23:45

bille

Don't call me Buff

Topicstarter
vaag, als ik hier kijk dan zie ik een stuk minder documentatie bij Windows dan bij Linux :? vaag hoor.. vandaar dat ik et niet kon vinden...

overgens is 262144 niet echt veel lijkt mij... ik heb temaken met ehm.. 9 variabelen die ieder 50 verschillende waarden kunnen hebben.. dus dat zijn 50^9= mogelijkheden 1953125000000000 en per X aantal mogelijke combinaties zit er 1 valide combinatie tussen en die moet gebruikt worden. Die wordt uitgezocht met behulp van de code die ik gegeven heb.

Echter heb ik eens even snel een testje gedaan met de volgende code:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Blaat {
    static int count = 0;

    public static void main(String[] args){
        Blaat myBlaat = new Blaat();
        myBlaat.calc();
        System.out.println("Count= "+count);
    }
    public void calc(){
        count++;
        if(count != 100000){
            calc();
        }
    }
}


en dat ding gaat al direct over zijn nek! zelfs wanneer ik -Xss128000000 (128MB) gebruik dan gaat ie direct over zijn nek... Als ik dan kijk naar de berekening van .oisyn .. dan valt me op dat in dit geval zelfs 100.000 keer al teveel is :?

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Hum jouw testje doet het hier op Linux prima. Niet alleen de documentatie is dus beter ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • bille
  • Registratie: Mei 2000
  • Laatst online: 05-08 23:45

bille

Don't call me Buff

Topicstarter
overgens denk ik dat het ook wel anders op te lossen is.. de lap code die ik heb neergezet is niet het aller mooiste staaltje programmeerwerk wat ik ooit heb neergezet ;) ik denk dat ik dat maar eens ga herschrijven dus.. het moet toch nog geoptimaliseerd worden..

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


  • bille
  • Registratie: Mei 2000
  • Laatst online: 05-08 23:45

bille

Don't call me Buff

Topicstarter
lol dat meen je niet bravenboer?!!! dat zou namelijk wel bijzonder asso zijn :P misschien dat het komt doordat ik gebruik maak van een IDE die ook al in JAVA draait :? maar dat lijkt me toch eigelijk niet.. want die verschillende apps zullen wel verschillende stacks hebben neem ik aan?

[ Voor 79% gewijzigd door bille op 28-11-2002 13:45 ]

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Toch wel :P .

Ik denk eerlijk gezegd dat je je JVM op of een of andere manier verkloot hebt. Misschien moet je hem even opnieuw installeren? Dit verschil zou wel erg merkwaardig zijn.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
bille: misschien dat het komt doordat ik gebruik maak van een IDE die ook al in JAVA draait :?
Mwah ik denk niet dat dat erg veel verschil maakt, zelfs al draait hij in dezelfde JVM.
die verschillende apps zullen wel verschillende stacks hebben neem ik aan?
Elke thread heeft een eigen stack. De applicatie wordt vanuit die IDE in ieder geval op een andere thread gestart (tenzij de IDE heeeeel erg slecht is ;) ).

Ik zou hem sowieso eens van de command line proberen te starten.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • bille
  • Registratie: Mei 2000
  • Laatst online: 05-08 23:45

bille

Don't call me Buff

Topicstarter
hmmm er lijkt iets mis te zijn met mijn java ofzo :? ik heb et es in 1 filetje gezet los van de IDE.. probeer ik te compilen krijg ik dit:

Blaat.java:3: illegal character: \160
áááápublicástaticávoidámain(String[]áargs){
^
Blaat.java:3: illegal character: \160
áááápublicástaticávoidámain(String[]áargs){
^
Blaat.java:3: illegal character: \160
áááápublicástaticávoidámain(String[]áargs){
^
Blaat.java:3: illegal character: \160
áááápublicástaticávoidámain(String[]áargs){

hmjah dat bedoelde ik dus.. vanaf de cmd gestart... en dus bovenstaande effect :/

overgens:
C:\>java -version
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)

[ Voor 24% gewijzigd door bille op 28-11-2002 13:49 ]

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Gokje, gebruik je Forte, Sun ONE Studio, Netbeans hoe het ook mogen heten? En heb je de code cut-n-pasted? Die fout kreeg ik vorige week nl. ook. Weet alleen niet wat de reden is :)

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • bille
  • Registratie: Mei 2000
  • Laatst online: 05-08 23:45

bille

Don't call me Buff

Topicstarter
ehm neej gebruik TogetherJ CC 6, maar idd wel copy/paste.. zal idd wel zo'n vage bugz0r zijn dan...

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies

Pagina: 1