Comments (10)
您好,感谢反馈这个问题,从现象来看似乎是由于Escape Analysis分析没有将第二次add1的BigDecimal做栈上分配导致的,应该属于C2编译的一个bug,根因还需要进一步分析。
从下面的log可以看到,第一执行的时候add1是能够将里面的BigDecimal a
和BigDecimal b
做栈上分配,而第二次执行funLong时则没有做栈上分配,从而导致性能差距较大。
[root@VM-235-31-centos BigDecimal]# /data/openjdk/jdk/build/linux-x86_64-server-fastdebug/images/jdk/bin/java -XX:+PrintEscapeAnalysis -XX:+PrintEliminateAllocations Foo
======== Connection graph for Foo::add1
invocation #0: 2 iterations and 0.000003 sec to build connection graph with 676 nodes and worklist size 21
JavaObject(3) NoEscape(NoEscape) [ 320F 316F [ 235 240 ]] 223 Allocate === 213 72 185 8 1 ( 59 58 33 1 1 1 1 78 1 1 10 1 22 ) [[ 224 225 226 233 234 235 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34)
LocalVar(13) [ 223P [ 240 ]] 235 Proj === 223 [[ 236 240 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34)
LocalVar(16) [ 235 223P [ 320b 316b ]] 240 CheckCastPP === 237 235 [[ 252 252 388 372 333 320 320 316 316 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34)
JavaObject(4) NoEscape(NoEscape) [ 168F 162F [ 73 78 ]] 61 Allocate === 48 6 7 8 1 ( 59 58 33 1 1 10 1 1 1 1 10 1 22 ) [[ 62 63 64 71 72 73 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33)
LocalVar(14) [ 61P [ 78 ]] 73 Proj === 61 [[ 74 78 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33)
LocalVar(17) [ 73 61P [ 168b 162b ]] 78 CheckCastPP === 75 73 [[ 91 91 388 372 252 223 217 183 168 168 162 162 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33)
JavaObject(5) NoEscape(NoEscape) [ 614F 610F [ 529 534 ]] 517 Allocate === 507 234 335 8 1 ( 59 58 33 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 448 1 396 ) [[ 518 519 520 527 528 529 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36)
LocalVar(15) [ 517P [ 534 ]] 529 Proj === 517 [[ 530 534 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36)
LocalVar(18) [ 529 517P [ 614b 610b ]] 534 CheckCastPP === 531 529 [[ 546 546 627 614 614 610 610 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36)
Scalar 534 CheckCastPP === 531 529 [[ 546 546 610 614 614 610 ]] #java/math/BigDecimal:NotNull:exact *,iid=517 Oop:java/math/BigDecimal:NotNull:exact *,iid=517 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36)
++++ Eliminated: 517 Allocate
Scalar 240 CheckCastPP === 237 235 [[ 252 252 320 316 316 320 ]] #java/math/BigDecimal:NotNull:exact *,iid=223 Oop:java/math/BigDecimal:NotNull:exact *,iid=223 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34)
++++ Eliminated: 223 Allocate
Scalar 78 CheckCastPP === 75 73 [[ 91 91 168 162 252 168 217 162 ]] #java/math/BigDecimal:NotNull:exact *,iid=61 Oop:java/math/BigDecimal:NotNull:exact *,iid=61 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33)
++++ Eliminated: 61 Allocate
======== Connection graph for Foo::funInt
invocation #0: 2 iterations and 0.000004 sec to build connection graph with 792 nodes and worklist size 29
JavaObject(9) NoEscape(NoEscape) [ 713F 709F [ 628 633 ]] 616 Allocate === 606 327 434 8 1 ( 147 146 21 1 1 29 1 91 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 547 1 495 ) [[ 617 618 619 626 627 628 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funInt @ bci:14 (line 17) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funInt @ bci:14 (line 17)
LocalVar(20) [ 616P [ 633 ]] 628 Proj === 616 [[ 629 633 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funInt @ bci:14 (line 17)
LocalVar(24) [ 628 616P [ 713b 709b ]] 633 CheckCastPP === 630 628 [[ 645 645 726 713 713 709 709 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funInt @ bci:14 (line 17)
JavaObject(10) NoEscape(NoEscape) [ 257F 246F 254F 243F [ 161 166 ]] 149 Allocate === 136 88 138 8 1 ( 147 146 21 1 1 29 1 91 102 1 1 1 1 102 1 112 ) [[ 150 151 152 159 160 161 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) Foo::funInt @ bci:14 (line 17) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) Foo::funInt @ bci:14 (line 17)
LocalVar(21) [ 149P [ 166 257b 246b ]] 161 Proj === 149 [[ 162 166 246 257 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) Foo::funInt @ bci:14 (line 17)
LocalVar(25) [ 161 149P [ 254b 243b ]] 166 CheckCastPP === 163 161 [[ 487 471 316 310 275 254 254 243 243 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) Foo::funInt @ bci:14 (line 17)
JavaObject(11) NoEscape(NoEscape) [ 416F 406F 413F 403F [ 328 333 ]] 316 Allocate === 306 160 277 8 1 ( 147 146 21 1 1 29 1 91 1 1 166 1 1 102 1 112 ) [[ 317 318 319 326 327 328 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funInt @ bci:14 (line 17) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funInt @ bci:14 (line 17)
LocalVar(22) [ 316P [ 333 416b 406b ]] 328 Proj === 316 [[ 329 333 406 416 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funInt @ bci:14 (line 17)
LocalVar(26) [ 328 316P [ 413b 403b ]] 333 CheckCastPP === 330 328 [[ 487 471 432 413 413 403 403 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funInt @ bci:14 (line 17)
Scalar 616 Allocate === 606 327 350 8 1 ( 147 146 21 1 1 29 1 91 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 547 1 112 ) [[ 617 618 619 626 627 628 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funInt @ bci:14 (line 17) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funInt @ bci:14 (line 17)
++++ Eliminated: 616 Allocate
Scalar 316 Allocate === 306 160 185 8 1 ( 147 146 21 1 1 29 1 91 1 1 166 1 1 102 1 112 ) [[ 317 318 319 326 327 328 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funInt @ bci:14 (line 17) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funInt @ bci:14 (line 17)
++++ Eliminated: 316 Allocate
Scalar 166 CheckCastPP === 163 161 [[ 310 ]] #java/math/BigDecimal:NotNull:exact *,iid=149 Oop:java/math/BigDecimal:NotNull:exact *,iid=149 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) Foo::funInt @ bci:14 (line 17)
++++ Eliminated: 149 Allocate
88
======== Connection graph for Foo::add1
invocation #0: 2 iterations and 0.000005 sec to build connection graph with 777 nodes and worklist size 38
JavaObject(3) NoEscape(NoEscape) NSR [ 352F 348F 442F 464F [ 262 267 212 441 ]] 250 Allocate === 230 26 27 8 1 ( 68 67 33 1 1 1 1 29 1 1 10 1 22 ) [[ 251 252 253 260 261 262 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34)
LocalVar(18) [ 250P [ 267 ]] 262 Proj === 250 [[ 263 267 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34)
LocalVar(24) [ 262 250P [ 352b 348b 212 ]] 267 CheckCastPP === 264 262 [[ 284 284 365 352 212 352 348 348 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34)
LocalVar(25) [ 239 267 1P 250P [ 441 ]] 212 Phi === 208 239 267 [[ 441 387 424 429 ]] #java/math/BigDecimal * Oop:java/math/BigDecimal * !jvms: Foo::add1 @ bci:8 (line 34)
LocalVar(31) [ 212 1P 250P [ 442b 464b ]] 441 CastPP === 434 212 [[ 464 442 442 453 464 ]] #java/math/BigDecimal:NotNull * Oop:java/math/BigDecimal:NotNull * !jvms: BigDecimal::add @ bci:12 (line 1380) Foo::add1 @ bci:14 (line 36)
JavaObject(4) NoEscape(NoEscape) NSR [ 183F 177F 413F 460F [ 82 87 29 392 ]] 70 Allocate === 48 6 7 8 1 ( 68 67 33 1 1 10 1 1 1 1 10 1 22 ) [[ 71 72 73 80 81 82 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33)
LocalVar(21) [ 70P [ 87 ]] 82 Proj === 70 [[ 83 87 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33)
LocalVar(27) [ 82 70P [ 183b 177b 29 ]] 87 CheckCastPP === 84 82 [[ 106 106 198 183 29 183 177 177 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33)
LocalVar(26) [ 57 87 1P 70P [ 392 ]] 29 Phi === 25 57 87 [[ 284 392 234 250 379 ]] #java/math/BigDecimal * Oop:java/math/BigDecimal * !orig=[378] !jvms: Foo::add1 @ bci:2 (line 33)
LocalVar(33) [ 29 1P 70P [ 413b 460b ]] 392 CastPP === 384 29 [[ 460 453 424 413 413 460 ]] #java/math/BigDecimal:NotNull * Oop:java/math/BigDecimal:NotNull * !jvms: Foo::add1 @ bci:14 (line 36)
JavaObject(5) NoEscape(NoEscape) NSR [ 694F 690F 756F [ 604 609 551 735 ]] 592 Allocate === 572 209 210 8 1 ( 68 67 33 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 513 1 461 ) [[ 593 594 595 602 603 604 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36)
LocalVar(22) [ 592P [ 609 ]] 604 Proj === 592 [[ 605 609 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36)
LocalVar(28) [ 604 592P [ 694b 551 690b ]] 609 CheckCastPP === 606 604 [[ 626 626 707 694 551 694 690 690 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36)
LocalVar(29) [ 581 609 1P 592P [ 735 ]] 551 Phi === 547 581 609 [[ 735 723 ]] #java/math/BigDecimal * Oop:java/math/BigDecimal * !orig=[722] !jvms: BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36)
LocalVar(35) [ 551 1P 592P [ 756b ]] 735 CastPP === 728 551 [[ 756 756 ]] #java/math/BigDecimal:NotNull * Oop:java/math/BigDecimal:NotNull * !jvms: Foo::add1 @ bci:21 (line 38)
======== Connection graph for Foo::funLong
invocation #0: 2 iterations and 0.000007 sec to build connection graph with 883 nodes and worklist size 42
JavaObject(5) NoEscape(NoEscape) NSR [ 782F 778F 844F [ 692 697 639 823 ]] 680 Allocate === 660 297 298 8 1 ( 159 158 21 1 1 29 1 94 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 601 1 549 ) [[ 681 682 683 690 691 692 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funLong @ bci:15 (line 26) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funLong @ bci:15 (line 26)
LocalVar(22) [ 680P [ 697 ]] 692 Proj === 680 [[ 693 697 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funLong @ bci:15 (line 26)
LocalVar(28) [ 692 680P [ 782b 778b 639 ]] 697 CheckCastPP === 694 692 [[ 714 714 795 782 639 782 778 778 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funLong @ bci:15 (line 26)
LocalVar(33) [ 669 697 1P 680P [ 823 ]] 639 Phi === 635 669 697 [[ 823 811 ]] #java/math/BigDecimal * Oop:java/math/BigDecimal * !orig=[810] !jvms: BigDecimal::add @ bci:20 (line 4973) BigDecimal::add @ bci:18 (line 4980) BigDecimal::add @ bci:38 (line 1381) Foo::add1 @ bci:14 (line 36) Foo::funLong @ bci:15 (line 26)
LocalVar(39) [ 639 1P 680P [ 844b ]] 823 CastPP === 816 639 [[ 844 844 ]] #java/math/BigDecimal:NotNull * Oop:java/math/BigDecimal:NotNull * !jvms: Foo::add1 @ bci:21 (line 38) Foo::funLong @ bci:15 (line 26)
JavaObject(6) NoEscape(NoEscape) NSR [ 440F 436F 530F 552F [ 350 355 300 529 ]] 338 Allocate === 318 120 121 8 1 ( 159 158 21 1 1 29 1 94 1 1 1 123 1 1 94 1 116 ) [[ 339 340 341 348 349 350 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funLong @ bci:15 (line 26) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funLong @ bci:15 (line 26)
LocalVar(23) [ 338P [ 355 ]] 350 Proj === 338 [[ 351 355 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funLong @ bci:15 (line 26)
LocalVar(29) [ 350 338P [ 440b 436b 300 ]] 355 CheckCastPP === 352 350 [[ 372 372 453 440 300 440 436 436 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:8 (line 34) Foo::funLong @ bci:15 (line 26)
LocalVar(31) [ 327 355 1P 338P [ 529 ]] 300 Phi === 296 327 355 [[ 529 475 512 517 ]] #java/math/BigDecimal * Oop:java/math/BigDecimal * !jvms: Foo::add1 @ bci:8 (line 34) Foo::funLong @ bci:15 (line 26)
LocalVar(37) [ 300 1P 338P [ 530b 552b ]] 529 CastPP === 522 300 [[ 552 530 530 541 552 ]] #java/math/BigDecimal:NotNull * Oop:java/math/BigDecimal:NotNull * !jvms: BigDecimal::add @ bci:12 (line 1380) Foo::add1 @ bci:14 (line 36) Foo::funLong @ bci:15 (line 26)
JavaObject(7) NoEscape(NoEscape) NSR [ 271F 267F 501F 548F [ 173 178 123 480 ]] 161 Allocate === 139 91 141 8 1 ( 159 158 21 1 1 29 1 94 1 94 1 1 1 1 94 1 116 ) [[ 162 163 164 171 172 173 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, top, bool ) BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) Foo::funLong @ bci:15 (line 26) !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) Foo::funLong @ bci:15 (line 26)
LocalVar(24) [ 161P [ 178 ]] 173 Proj === 161 [[ 174 178 ]] #5 !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) Foo::funLong @ bci:15 (line 26)
LocalVar(30) [ 173 161P [ 271b 267b 123 ]] 178 CheckCastPP === 175 173 [[ 197 197 286 271 123 271 267 267 ]] #java/math/BigDecimal:NotNull:exact * Oop:java/math/BigDecimal:NotNull:exact * !jvms: BigDecimal::valueOf @ bci:20 (line 1293) Foo::add1 @ bci:2 (line 33) Foo::funLong @ bci:15 (line 26)
LocalVar(32) [ 148 178 1P 161P [ 480 ]] 123 Phi === 119 148 178 [[ 372 480 322 338 467 ]] #java/math/BigDecimal * Oop:java/math/BigDecimal * !orig=[466] !jvms: Foo::add1 @ bci:2 (line 33) Foo::funLong @ bci:15 (line 26)
LocalVar(38) [ 123 1P 161P [ 501b 548b ]] 480 CastPP === 472 123 [[ 548 541 512 501 501 548 ]] #java/math/BigDecimal:NotNull * Oop:java/math/BigDecimal:NotNull * !jvms: Foo::add1 @ bci:14 (line 36) Foo::funLong @ bci:15 (line 26)
2987
from tencentkona-8.
非常感谢您的回馈,我上午也做了一些其他尝试,也分享给您。
新的funLong2() 方法使用 while 循环,即使使用 long 作为变量,也不会造成第二个方法变慢,这个很重要,
import java.math.BigDecimal;
public class Foo {
public static void main(String[] args) {
System.out.println(funInt());
System.out.println(funLong2());
}
static long funInt() {
long start = System.currentTimeMillis();
for(int i = 0; i < Integer.MAX_VALUE; i++) {
add1((long) i);
}
return System.currentTimeMillis() - start;
}
static long funLong() {
long start = System.currentTimeMillis();
for(long i = 0L; i < (long) Integer.MAX_VALUE; i++) {
add1(i);
}
return System.currentTimeMillis() - start;
}
static long funLong2() {
long start = System.currentTimeMillis();
long i = 0L;
long len = (long) Integer.MAX_VALUE;
while(i++ < len){
add1(i);
}
return System.currentTimeMillis() - start;
}
static void add1(long i) {
BigDecimal a = BigDecimal.valueOf(i, 2);
BigDecimal b = BigDecimal.valueOf(i, 2);
BigDecimal c = a.add(b);
if(c.scale() != 2){
throwError();
}
}
static void add2(long i) {
long a = i;
long b = i + 1L;
long c = a + b;
if(c < 0L){
throwError();
}
}
static void throwError() {
throw new RuntimeException("error");
}
}
第二点,我最初怀疑是分配了更多的对象导致 GC,但我修改了 add1(),如果 c 变量也是直接创建一个BigDecimal,而不是使用 加法 运算,也不会出现问题。
from tencentkona-8.
我发现 https://heapdump.cn/question/3686888 也提到这个问题。
from tencentkona-8.
openjdk主干库截止目前JDK19(afa5d4ced38b7f3752932c28af96d8fc600d1df7)的Escape Analysis的实现依然比较脆弱,很容易导致EA分析失败,从而无法进行Stack Allocation for Aggregates,具体参见文章https://cr.openjdk.java.net/~cslucas/escape-analysis/EscapeAnalysis.html
from tencentkona-8.
非常感谢您的回馈,我上午也做了一些其他尝试,也分享给您。
新的funLong2() 方法使用 while 循环,即使使用 long 作为变量,也不会造成第二个方法变慢,这个很重要,
import java.math.BigDecimal; public class Foo { public static void main(String[] args) { System.out.println(funInt()); System.out.println(funLong2()); } static long funInt() { long start = System.currentTimeMillis(); for(int i = 0; i < Integer.MAX_VALUE; i++) { add1((long) i); } return System.currentTimeMillis() - start; } static long funLong() { long start = System.currentTimeMillis(); for(long i = 0L; i < (long) Integer.MAX_VALUE; i++) { add1(i); } return System.currentTimeMillis() - start; } static long funLong2() { long start = System.currentTimeMillis(); long i = 0L; long len = (long) Integer.MAX_VALUE; while(i++ < len){ add1(i); } return System.currentTimeMillis() - start; } static void add1(long i) { BigDecimal a = BigDecimal.valueOf(i, 2); BigDecimal b = BigDecimal.valueOf(i, 2); BigDecimal c = a.add(b); if(c.scale() != 2){ throwError(); } } static void add2(long i) { long a = i; long b = i + 1L; long c = a + b; if(c < 0L){ throwError(); } } static void throwError() { throw new RuntimeException("error"); } }第二点,我最初怀疑是分配了更多的对象导致 GC,但我修改了 add1(),如果 c 变量也是直接创建一个BigDecimal,而不是使用 加法 运算,也不会出现问题。
您说的这个测试主要是由于i=0传入static void add1(long i)
,导致add1最终inline了java.math.BigDecimal::zeroValueOf
,使得该函数导致控制流改变,进而EA失效。而您的funLong2
是从1开始调用add1
,java.math.BigDecimal::zeroValueOf
调用不到,EA此时是有效的。
335 31 % 3 Foo::funInt @ 6 (29 bytes) made not entrant
@ 14 Foo::add1 (32 bytes) inline (hot)
@ 2 java.math.BigDecimal::valueOf (46 bytes) inline (hot)
@ 42 java.math.BigDecimal::<init> (27 bytes) inline (hot)
@ 1 java.lang.Number::<init> (5 bytes) inline (hot)
@ 1 java.lang.Object::<init> (1 bytes) inline (hot)
@ 8 java.math.BigDecimal::valueOf (46 bytes) inline (hot)
@ 42 java.math.BigDecimal::<init> (27 bytes) inline (hot)
@ 1 java.lang.Number::<init> (5 bytes) inline (hot)
@ 1 java.lang.Object::<init> (1 bytes) inline (hot)
@ 14 java.math.BigDecimal::add (113 bytes) inline (hot)
@ 38 java.math.BigDecimal::add (189 bytes) inline (hot)
@ 18 java.math.BigDecimal::add (42 bytes) inline (hot)
@ 2 java.math.BigDecimal::add (26 bytes) inline (hot)
@ 20 java.math.BigDecimal::valueOf (46 bytes) inline (hot)
@ 42 java.math.BigDecimal::<init> (27 bytes) inline (hot)
@ 1 java.lang.Number::<init> (5 bytes) inline (hot)
@ 1 java.lang.Object::<init> (1 bytes) inline (hot)
@ 21 java.math.BigDecimal::scale (5 bytes) accessor
1043 44 % 4 Foo::funLong @ 6 (31 bytes)
1089 42 % 3 Foo::funLong @ 6 (31 bytes) made not entrant
@ 15 Foo::add1 (32 bytes) inline (hot)
@ 2 java.math.BigDecimal::valueOf (46 bytes) inline (hot)
@ 16 java.math.BigDecimal::zeroValueOf (32 bytes) low call site frequency
@ 42 java.math.BigDecimal::<init> (27 bytes) inline (hot)
@ 1 java.lang.Number::<init> (5 bytes) inline (hot)
@ 1 java.lang.Object::<init> (1 bytes) inline (hot)
@ 8 java.math.BigDecimal::valueOf (46 bytes) inline (hot)
@ 16 java.math.BigDecimal::zeroValueOf (32 bytes) low call site frequency
@ 42 java.math.BigDecimal::<init> (27 bytes) inline (hot)
@ 1 java.lang.Number::<init> (5 bytes) inline (hot)
@ 1 java.lang.Object::<init> (1 bytes) inline (hot)
@ 14 java.math.BigDecimal::add (113 bytes) inline (hot)
@ 38 java.math.BigDecimal::add (189 bytes) inline (hot)
@ 18 java.math.BigDecimal::add (42 bytes) inline (hot)
@ 2 java.math.BigDecimal::add (26 bytes) inline (hot)
@ 20 java.math.BigDecimal::valueOf (46 bytes) inline (hot)
@ 16 java.math.BigDecimal::zeroValueOf (32 bytes) low call site frequency
@ 42 java.math.BigDecimal::<init> (27 bytes) inline (hot)
@ 1 java.lang.Number::<init> (5 bytes) inline (hot)
@ 1 java.lang.Object::<init> (1 bytes) inline (hot)
@ 21 java.math.BigDecimal::scale (5 bytes) accessor
from tencentkona-8.
@casparcwang 我想再请教一下,为什么JAVA中,for 循环使用int 作为变量 比 long 作为变量,其性能要快 2~3 倍,while循环也是如此,感谢。
from tencentkona-8.
@casparcwang 我想再请教一下,为什么JAVA中,for 循环使用int 作为变量 比 long 作为变量,其性能要快 2~3 倍,while循环也是如此,感谢。
在java里面,for或者while循环除了int/long作为循环变量,其他均相同的情况下,应该是没有本质的区别的,特别是在解释器模式(-Xint)下或者C1编译器模式(-XX:TieredStopAtLevel=3)下。C2的话可能会根据inline的情况而有所不同,特别是在OSR的情况下,您最初的例子中如果把add1改成add2,并且funcInt和funcLong多执行几次,就会发现最终两者的执行时间是一样的,都为0.
当然在你说的例子中,前一两次执行的时候使用的是OSR的JIT代码,int和long作为循环变量时的jit代码效率不同,是一个值得分析和改进的点。
from tencentkona-8.
非常感谢您的回答,学习到了很多的知识。
from tencentkona-8.
https://www.cnblogs.com/thisiswhy/p/16657667.html
这篇文章解释了long 和 int 作为循环变量时的区别,即 long 作为变量时会插入安全点。
from tencentkona-8.
https://www.cnblogs.com/thisiswhy/p/16657667.html
这篇文章解释了long 和 int 作为循环变量时的区别,即 long 作为变量时会插入安全点。
我个人是不建议采用Thread.sleep这种写法的,int作为循环变量确实现在没有插入safepoint instruction,而long作为循环变量会插入,但是一般遇到这种情况是推荐加上选项-XX:+UseCountedLoopSafepoints
来强制编译插入safepoint instruction。
from tencentkona-8.
Related Issues (20)
- aarch64-8.0.12 镜像中文论码 HOT 4
- SECURITY.md
- 8.0.7之后版本docker镜像无法启动报错? HOT 5
- konajdk/konajdk:8没有字体库 HOT 1
- 8.0.10fiber版本遇到崩溃 HOT 2
- kona是否支持在arm上编译? HOT 1
- KonaJDK-8.0.8-u312在容器中有性能问题? HOT 3
- StringIndexOutOfBoundsException with empty input in sun.tools.jar.Manifest.isManifestName("") HOT 2
- libfontmanager.so: libfreetype.so.6: cannot open shared object file HOT 11
- konaJDK 8 有针对国产环境arm架构下ForceSafepoint的优化? HOT 7
- Kona的协程会自动回收么
- 请问 Kona 的构建参数列表有哪些呀,想了解下 HOT 5
- CDS 支持源码 HOT 2
- Konajdk8 基础镜像的优化建议 HOT 5
- Should update the supported platforms in README HOT 3
- does the coroutine support ObjectMonitor? HOT 2
- 用Kona的Fiber解决Http阻塞的问题 HOT 4
- 是否支持 native方法 调度 HOT 6
- 请问 OWST 相关 commit 或 patch 有吗? HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tencentkona-8.