Interesting tool, I'll try it on some of my code.

I think that onebyte doesn't escape because I also am the implementer of
the other read() overloads.   I was pointing out that implementing the
single byte read could be implemented in terms of the multi byte read.
 However, it would be unpleasant if it actually allocated memory to do the
read.   If onebyte can be allocated on the stack, how do I know it actually
is?  (or better yet, not allocated at all)

On Thu, Jan 25, 2018 at 2:49 PM, Chris Newland <[email protected]>
wrote:

> Hi Carl,
>
> HotSpot's LogCompilation output (enable with
> -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation) does contain
> information about eliminated allocations (and also elided locks) from EA
> but it's tricky to read by eye.
>
> JITWatch (https://github.com/AdoptOpenJDK/jitwatch) is a free open-source
> tool (disclaimer: I'm the author) that can highlight heap allocations which
> were avoided due to the JIT's EA. I made a video on how to use this
> feature: https://www.youtube.com/watch?v=LK1Ain1JDlQ
>
> Kris Mok and Vladimir Ivanov (HotSpot experts) gave some great info on how
> OSR compilation works including variable scope: https://github.com/
> AdoptOpenJDK/jitwatch/wiki/Understanding-the-On-Stack-Replacement-(OSR)-
> optimisation-in-the-HotSpot-C1-compiler
>
> In your example below, why do you think the array 'onebyte' doesn't
> escape? I can see it passed as a parameter to method read(byte[], int,
> int). If that read method is not inlined (inlining is attempted before EA
> is applied) then this would be classed as an ArgEscape (object escapes by
> passing it as an argument to another method) and could not benefit from
> avoiding the heap allocation.
>
> Cheers,
>
> Chris
> @chriswhocodes
>
>
> On Thursday, 25 January 2018 19:48:59 UTC, Carl Mastrangelo wrote:
>>
>> That's pretty cool.    I'm curious: Does -Xcomp work because it can show
>> the variable doesn't escape, or because of deadcode elimination?   For
>> example, when implementing an InputStream, one way to implement read would
>> be:
>>
>>     @Override
>>     public int read() {
>>       byte[] onebyte = new byte[1];
>>       int ret = read(onebyte, 0, 1);
>>       if (ret == -1) {
>>         return -1;
>>       }
>>       return 0xFF & onebyte[0];
>>     }
>>
>> How can I tell that the compiler knows onebyte array doesn't escape?
>>
>>
>>
>> On Thu, Jan 25, 2018 at 12:13 AM, Aleksey Shipilev <[email protected]
>> > wrote:
>>
>>> On 01/25/2018 03:44 AM, 'Carl Mastrangelo' via mechanical-sympathy wrote:
>>> > Consider the following code:
>>> >
>>> > public class Test {
>>> >   static volatile Integer discard;
>>> >   public static void main(String [] args) throws InterruptedException {
>>> >     printMemory();
>>> >     System.gc();
>>> >     printMemory();
>>> >     int iterations = 1000;
>>> >     int[] vals = new int[100_000_000];
>>> >     while (args.length == 0) {
>>> >       printMemory();
>>> >       System.gc();
>>> >       Thread.sleep(200);
>>> >       discard = iterations++;
>>> >     }
>>> >   }
>>> >
>>> >   private static void printMemory() {
>>> >     System.out.println(Runtime.getRuntime().totalMemory() -
>>> Runtime.getRuntime().freeMemory());
>>> >   }
>>> > }
>>> >
>>> > I am surprised to see the memory used by this code starts at about
>>> 200MB, goes up to 600MB, but
>>> > never seems to go back down.  The large int array accounts for the
>>> memory usage jump, but it never
>>> > seems to be garbage collected.  Why?   The variable is never read
>>> after it is allocated.  It cannot
>>> > be reordered by the compiler to be after the while loop, because I can
>>> see the memory jump.  I am
>>> > intentionally allocating memory in the loop by boxing the integer.
>>> Enabling +PrintCompilation and
>>> > PrintInlining never shows main() being inlined; perhaps it is not
>>> being compiled?
>>>
>>> This is not escape analysis. It is more about compiler able to figure
>>> out the reachability of local
>>> variable, and let GC act:
>>>   https://shipilev.net/jvm-anatomy-park/8-local-var-reachability/
>>>
>>> It is predicated on the condition that method is actually compiled and
>>> optimized accordingly. OSR
>>> would not cut it here, I think, because the OSR version of the method
>>> would still treat that
>>> variable alive.
>>>
>>> $ java Test
>>> 10548688
>>> 260648
>>> 410809368
>>> 410673344
>>> 400260544
>>> 400260544
>>> 400260544
>>> 400260544
>>> 400260544
>>> 400260544
>>>
>>> It changes if you compile the method before entering it:
>>>
>>> $ java -Xcomp Test
>>> 73841024
>>> 296240
>>> 421393656
>>> 10580272
>>> 10580608
>>> 10580608
>>> 10580608
>>> 10580608
>>>
>>> Thanks,
>>> -Aleksey
>>>
>>> --
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "mechanical-sympathy" group.
>>> To unsubscribe from this topic, visit https://groups.google.com/d/to
>>> pic/mechanical-sympathy/hj5VaYIoNiE/unsubscribe.
>>> To unsubscribe from this group and all its topics, send an email to
>>> [email protected].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
> You received this message because you are subscribed to a topic in the
> Google Groups "mechanical-sympathy" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/mechanical-sympathy/hj5VaYIoNiE/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to