java - Why does this method print 4? -
i wondering happens when try catch stackoverflowerror , came following method:
class randomnumbergenerator { static int cnt = 0; public static void main(string[] args) { try { main(args); } catch (stackoverflowerror ignore) { system.out.println(cnt++); } } }
now question:
why method print '4'?
i thought maybe because system.out.println()
needs 3 segments on call stack, don't know number 3 comes from. when @ source code (and bytecode) of system.out.println()
, lead far more method invocations 3 (so 3 segments on call stack not sufficient). if it's because of optimizations hotspot vm applies (method inlining), wonder if result different on vm.
edit:
as output seems highly jvm specific, result 4 using
java(tm) se runtime environment (build 1.6.0_41-b02)
java hotspot(tm) 64-bit server vm (build 20.14-b01, mixed mode)
explanation why think question different understanding java stack:
my question not why there cnt > 0 (obviously because system.out.println()
requires stack size , throws stackoverflowerror
before gets printed), why has particular value of 4, respectively 0,3,8,55 or else on other systems.
i think others have done job @ explaining why cnt > 0, there's not enough details regarding why cnt = 4, , why cnt varies among different settings. attempt fill void here.
let
- x total stack size
- m stack space used when enter main first time
- r stack space increase each time enter main
- p stack space necessary run
system.out.println
when first main, space left on x-m. each recursive call takes r more memory. 1 recursive call (1 more original), memory use m + r. suppose stackoverflowerror thrown after c successful recursive calls, is, m + c * r <= x , m + c * (r + 1) > x. @ time of first stackoverflowerror, there's x - m - c * r memory left.
to able run system.out.prinln
, need p amount of space left on stack. if happens x - m - c * r >= p, 0 printed. if p requires more space, remove frames stack, gaining r memory @ cost of cnt++.
when println
able run, x - m - (c - cnt) * r >= p. if p large particular system, cnt large.
let's @ examples.
example 1: suppose
- x = 100
- m = 1
- r = 2
- p = 1
then c = floor((x-m)/r) = 49, , cnt = ceiling((p - (x - m - c*r))/r) = 0.
example 2: suppose that
- x = 100
- m = 1
- r = 5
- p = 12
then c = 19, , cnt = 2.
example 3: suppose
- x = 101
- m = 1
- r = 5
- p = 12
then c = 20, , cnt = 3.
example 4: suppose
- x = 101
- m = 2
- r = 5
- p = 12
then c = 19, , cnt = 2.
thus, see both system (m, r, , p) , stack size (x) affects cnt.
as side note, not matter how space catch
requires start. long there not enough space catch
, cnt not increase, there no external effects.
edit
i take said catch
. play role. suppose requires t amount of space start. cnt starts increment when leftover space greater t, , println
runs when leftover space greater t + p. adds step calculations , further muddies muddy analysis.
edit
i found time run experiments theory. unfortunately, theory doesn't seem match experiments. happens different.
experiment setup: ubuntu 12.04 server default java , default-jdk. xss starting @ 70,000 @ 1 byte increments 460,000.
the results available at: https://www.google.com/fusiontables/datasource?docid=1xkjhd4s8bilghe6gzbcfus3vt5mps_onscjwdbm i've created version every repeated data point removed. in other words, points different previous shown. makes easier see anomalies. https://www.google.com/fusiontables/datasource?docid=1xg_srzrrnasepwzonhqeakuzlhiam9vbedwfsua
Comments
Post a Comment