-1

I have a primality testing routine that is running out of memory and I want to find the value that it is barfing on, but I can't print it out! Relevant code fragment:

try{
            // truncate left to right
            for( int xTruncation = 1; xTruncation < lenValue; xTruncation++ ){
                integerValue[0]--;
                long value = Arithmetic.integerToLong10( integerValue );
                if( ! Numbers.primeIs( value ) ) continue NextPermutation; // the number is not prime
            }
            integerValue[0] = lenValue; // restore length

            // truncate right to left
            for( int xTruncation = 1; xTruncation < lenValue; xTruncation++ ){
                Arithmetic.integerReduce( integerValue, 1 );
                long value = Arithmetic.integerToLong10( integerValue );
                if( ! Numbers.primeIs( value ) ) continue NextPermutation; // the number is not prime
            }
} catch( Throwable t ) {
    System.out.println( "last value: " + nValue );
}

Here is the output:

23
37
73
313
317
373
797
3137
3797
739397
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at cra.common.Numbers_jsc.factor(Numbers.java:153)
    at cra.common.Numbers_jsc.primeIs(Numbers.java:78)
    at Euler50.Euler_37(Euler50.java:803)
    at Euler50.main(Euler50.java:15)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

The System.out.println in the catch clause never gets called. How can I print out the problematic value?

Tyler Durden
  • 11,156
  • 9
  • 64
  • 126
  • It seems like your loop can be combined, and you also don't show where your label is leading you to after the continue. – Makoto Jun 21 '13 at 15:49
  • exactly how could the exception handler code run? By definition you've run out of memory, so there's no more memory to do whatever allocations the handler requires (temp variables to build the exception string, backtrace, etc...). – Marc B Jun 21 '13 at 15:50
  • 1
    Where exactly is the exception thrown? Is Numbers.java:153 perhaps the very line within the catch? (I think this is pretty much the only possible way this could happen.) – Sebastian Redl Jun 21 '13 at 15:54
  • This is not a duplicate, I know how to catch the error, the question is how to PRINT after the error is caught. – Tyler Durden Jun 21 '13 at 15:54
  • 2
    The basic problem is that by the time you catch the exception there is not enough space left to do anything. You can SOMETIMES circumvent this by preallocating a lot of storage (several small/medium objects vs one large) and then zeroing the references to that storage before attempting to print. – Hot Licks Jun 21 '13 at 15:56
  • @TylerDurden Start by putting a breakpoint in the error handling block. Is the breakpoint hit? – Theodoros Chatzigiannakis Jun 21 '13 at 15:57
  • @TheodorosChatzigiannakis - Or maybe put a println there (;-)) – Hot Licks Jun 21 '13 at 15:57
  • @Theodoros Chatzigiannakis nice idea, but unfortunately the breakpoint does not get hit – Tyler Durden Jun 21 '13 at 15:59
  • One would observe that you're narrowing in on the problematic value. This should be quite reproducible, so that with repeated runs you can narrow things down further. – Hot Licks Jun 21 '13 at 16:02
  • @Sebastian Redl Sebastian is right! The try was not around the offending line. I assumed the prime tests in the fragment shown were causing the exception, but there was an earlier prime test outside of the try that was the true location. After I included it in the Try it worked. Last value was 319291392. Thanks – Tyler Durden Jun 21 '13 at 16:02
  • Also, it's possible you weren't able to print because you were trying to concatenate a string in your catch. It has to allocate memory and you're already out of it. – anthonyvd Jun 21 '13 at 16:33

1 Answers1

0

You can add the System.out.println before the exception thrown. For example:

try{
            // truncate left to right
            for( int xTruncation = 1; xTruncation < lenValue; xTruncation++ ){
                integerValue[0]--;

                System.out.println( "integerValue: " + integerValue );
                long value = Arithmetic.integerToLong10( integerValue );
                System.out.println( "value: " + value );
                if( ! Numbers.primeIs( value ) ) continue NextPermutation; // the number is not prime
            }
            integerValue[0] = lenValue; // restore length

            // truncate right to left
            for( int xTruncation = 1; xTruncation < lenValue; xTruncation++ ){
                Arithmetic.integerReduce( integerValue, 1 );
                System.out.println( "integerValue: " + integerValue );
                long value = Arithmetic.integerToLong10( integerValue );
                System.out.println( "value: " + value );
                if( ! Numbers.primeIs( value ) ) continue NextPermutation; // the number is not prime
            }
} catch( Throwable t ) {
    System.out.println( "last value: " + nValue );
}
messivanio
  • 2,263
  • 18
  • 24