Putting a breakpoint in a non reachable thread forces it to run

Multi tool use
Multi tool use












8















I have a strange issue with this code:



class Test {
private static boolean test = false;

public static void main(String args) {
new Thread(() -> {
while (true) {
if (test) {
System.out.println("Print when breakpoint here!");
test = false;
}
}
}, "Thread1").start();

new Thread(() -> {
while (true) {
System.out.println("Print always");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
test = true;
}
}, " Thread2").start();
}
}


As I expected, since boolean test is not volatile, Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything. But when I put a breakpoint at the line System.out.println("Prints when put a breakpoint here!"); It will reaches there and prints the line! What's really happening by putting a breakpoint? Does it force the program to directly read the value of variable from memory? Or something else is happening?










share|improve this question

























  • Breakpoint is just used to debug the java application or classes, no way related to variables in memory

    – Deadpool
    Dec 28 '18 at 21:48











  • @Deadpool As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?

    – Spara
    Dec 28 '18 at 21:54


















8















I have a strange issue with this code:



class Test {
private static boolean test = false;

public static void main(String args) {
new Thread(() -> {
while (true) {
if (test) {
System.out.println("Print when breakpoint here!");
test = false;
}
}
}, "Thread1").start();

new Thread(() -> {
while (true) {
System.out.println("Print always");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
test = true;
}
}, " Thread2").start();
}
}


As I expected, since boolean test is not volatile, Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything. But when I put a breakpoint at the line System.out.println("Prints when put a breakpoint here!"); It will reaches there and prints the line! What's really happening by putting a breakpoint? Does it force the program to directly read the value of variable from memory? Or something else is happening?










share|improve this question

























  • Breakpoint is just used to debug the java application or classes, no way related to variables in memory

    – Deadpool
    Dec 28 '18 at 21:48











  • @Deadpool As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?

    – Spara
    Dec 28 '18 at 21:54
















8












8








8








I have a strange issue with this code:



class Test {
private static boolean test = false;

public static void main(String args) {
new Thread(() -> {
while (true) {
if (test) {
System.out.println("Print when breakpoint here!");
test = false;
}
}
}, "Thread1").start();

new Thread(() -> {
while (true) {
System.out.println("Print always");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
test = true;
}
}, " Thread2").start();
}
}


As I expected, since boolean test is not volatile, Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything. But when I put a breakpoint at the line System.out.println("Prints when put a breakpoint here!"); It will reaches there and prints the line! What's really happening by putting a breakpoint? Does it force the program to directly read the value of variable from memory? Or something else is happening?










share|improve this question
















I have a strange issue with this code:



class Test {
private static boolean test = false;

public static void main(String args) {
new Thread(() -> {
while (true) {
if (test) {
System.out.println("Print when breakpoint here!");
test = false;
}
}
}, "Thread1").start();

new Thread(() -> {
while (true) {
System.out.println("Print always");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
test = true;
}
}, " Thread2").start();
}
}


As I expected, since boolean test is not volatile, Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything. But when I put a breakpoint at the line System.out.println("Prints when put a breakpoint here!"); It will reaches there and prints the line! What's really happening by putting a breakpoint? Does it force the program to directly read the value of variable from memory? Or something else is happening?







java multithreading debugging breakpoints






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 29 '18 at 13:36







Spara

















asked Dec 28 '18 at 21:35









SparaSpara

1




1













  • Breakpoint is just used to debug the java application or classes, no way related to variables in memory

    – Deadpool
    Dec 28 '18 at 21:48











  • @Deadpool As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?

    – Spara
    Dec 28 '18 at 21:54





















  • Breakpoint is just used to debug the java application or classes, no way related to variables in memory

    – Deadpool
    Dec 28 '18 at 21:48











  • @Deadpool As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?

    – Spara
    Dec 28 '18 at 21:54



















Breakpoint is just used to debug the java application or classes, no way related to variables in memory

– Deadpool
Dec 28 '18 at 21:48





Breakpoint is just used to debug the java application or classes, no way related to variables in memory

– Deadpool
Dec 28 '18 at 21:48













@Deadpool As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?

– Spara
Dec 28 '18 at 21:54







@Deadpool As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?

– Spara
Dec 28 '18 at 21:54














3 Answers
3






active

oldest

votes


















7















As I expected, since boolean test is not volatile Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything.




Your expectation is incorrect.



According to the Java Language Specification, if one thread updates a non-volatile shared variable and another thread subsequently reads it without appropriate synchronization then the second thread may see the new value, or it may see an earlier value.



So what you are seeing is allowed by the JLS.





In practice, when a debug agent is attached to a JVM, it will typically JIT compile methods at a lower optimization level ... or execute them using the bytecode interpreter. This is likely to happen for methods with breakpoints set in them, and when you are single-stepping1. This may result in different behavior for code that uses shared variables without proper synchronization when you debug it.



This is one of the reasons that debugging problems caused by inadequate synchronization is difficult.






As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?




That is what happens when you debug C / C++. It is not specified how a JVM handles this, but a typical JVM has other options for implementing breakpoints ... because of bytecodes and JIT compilation.






When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep?




The sleep will cause the current thread to be suspended. What happens at the implementation level is not specified. However, it is likely that the native thread mechanisms will flush any outstanding writes (i.e. dirty cache entries) for the suspended thread to memory ... as part of the process of performing a thread context switch.



Similarly, if you use print statements, a typical I/O stack has internal synchronization that can trigger cache flushes, etc. This can also alter the behavior of the code that you are trying to debug.



However, I should stress that these behaviors are not specified.





1 - A JIT optimizer is allowed to reorder assignments provided that this doesn't alter single-threaded behavior. But, if you are debugging a method and observing that values of variables, the effects of the reordering are visible (to the programmer). De-optimizing / interpreting avoids this. Fortunately, a modern JVM / debug agent can do this "on the fly" as required.






share|improve this answer


























  • Thanks man, There is another ambiguous point. When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep? I guess when interrupt Thread1 with sleep when it back to continue it will use fresh value of test. Am I right?

    – Spara
    Dec 29 '18 at 8:42



















4














Warning: this answer is based mostly on how .Net debuggers work but I expect similar behavior between two runtimes. I expect JVM to allow per-method re-JIT-ing at run time as it already can replace method with HotSpot JIT.



There is some existing articles and posts about what optimizations are turned off for debugging like AMD: perf when debugging enabled, Side Effects of running the JVM in debug mode, Will Java app slow down by presence of -Xdebug or only when stepping through code?. They hint that at least when there is an exception code takes significantly different code path under debugger which may be how breakpoints are implemented.





Many debuggers turn off optimizations (compile time if you allow to recompile code and JIT time if you debugging existing code) when you debug the code. In .Net world impact is global - when debugger is attached it can switch all future JIT compilations to non-optimized path, I expect Java/JVM to support more granular control to allow de-optimizing only methods that may need to stop in debugger. This is done to allow you to clearly see all values of all variables. Otherwise half of the information sometimes including method calls and local/member variables is not available.



"uses local cache value of test" is optimization (likely at JIT time) - so when you start debugging the code (or enable some sort of step-through with breakpoints) it will switch off optimization and read from memory every time thus essentially making variable close to volatile (still not necessary to behave that way all the time but close).



Depending on debugger you use you may disable such behavior (but debugging will be much harder).






share|improve this answer


























  • Thanks for your answer, But It will not print on debugging mode, It will just print when I put the breakpoint, And when I remove the breakpoint it will not print anymore!

    – Spara
    Dec 28 '18 at 22:02











  • @Spara I expect Java debuggers to be smarter than .Net once (which I really based my answer on) and re-JIT single method when you want to add breakpoint in one. Try to disable optimizations (stackoverflow.com/questions/5242405/…) and see if you get the same behavior you get with the breakpoint.

    – Alexei Levenkov
    Dec 28 '18 at 22:07













  • With disabling optimization there will be no thread caches and so it will always print the line with or without a breakpoint

    – Spara
    Dec 28 '18 at 22:09






  • 1





    @Spara yes, that's what I believe happens - when you want to step-through a method it had to be de-optimized and would behave the same way as if there were no optimizations enabled in a first place. The only info I found about JVM's behavior talk about de-optimizing code throwing exceptions - so you need a JVM+JVMTI+JDI expert to answer this for real. I'd recommend adding bounty when you can.

    – Alexei Levenkov
    Dec 29 '18 at 1:36






  • 1





    @Spara side note: I'd be very concern about writing code that explicitly relies on run-time optimization behavior (I assume you just have this as an example of strange behavior and not something you actually use in production).

    – Alexei Levenkov
    Dec 29 '18 at 1:37



















1














When you run code, it goes through a couple of stages of optimisation. Initially it is interpreted and your boolean variable might be consistently visible, however at the highest level of optimisation, the value can be inlined (not just cached) and you never see the change. The point at which this happens depends on how many times the code has looped and when the code is compiled and replaced in the background.



When you add logging or break points or sleep(1) you slow down the application and takes longer to reach the threshold at which the code is optimised. This means you avoid seeing the issue esp if it's a race condition.






share|improve this answer
























  • So you mean by slowing down the application, Optimization would not do anything?

    – Spara
    Dec 29 '18 at 9:05











  • I added for (int i = 0 ; i < Integer.MAX_VALUE; i++); at top of if statement in Thread1 and it printed the line. So it seems if the threshold passes JVM would not optimize the thread.

    – Spara
    Dec 29 '18 at 10:58











  • @Spara this loop will trigger the method to be compiled based on the runtime information it has (i.e. for the rest of the code none as it hasn't run it)

    – Peter Lawrey
    Dec 29 '18 at 20:43











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53964510%2fputting-a-breakpoint-in-a-non-reachable-thread-forces-it-to-run%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









7















As I expected, since boolean test is not volatile Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything.




Your expectation is incorrect.



According to the Java Language Specification, if one thread updates a non-volatile shared variable and another thread subsequently reads it without appropriate synchronization then the second thread may see the new value, or it may see an earlier value.



So what you are seeing is allowed by the JLS.





In practice, when a debug agent is attached to a JVM, it will typically JIT compile methods at a lower optimization level ... or execute them using the bytecode interpreter. This is likely to happen for methods with breakpoints set in them, and when you are single-stepping1. This may result in different behavior for code that uses shared variables without proper synchronization when you debug it.



This is one of the reasons that debugging problems caused by inadequate synchronization is difficult.






As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?




That is what happens when you debug C / C++. It is not specified how a JVM handles this, but a typical JVM has other options for implementing breakpoints ... because of bytecodes and JIT compilation.






When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep?




The sleep will cause the current thread to be suspended. What happens at the implementation level is not specified. However, it is likely that the native thread mechanisms will flush any outstanding writes (i.e. dirty cache entries) for the suspended thread to memory ... as part of the process of performing a thread context switch.



Similarly, if you use print statements, a typical I/O stack has internal synchronization that can trigger cache flushes, etc. This can also alter the behavior of the code that you are trying to debug.



However, I should stress that these behaviors are not specified.





1 - A JIT optimizer is allowed to reorder assignments provided that this doesn't alter single-threaded behavior. But, if you are debugging a method and observing that values of variables, the effects of the reordering are visible (to the programmer). De-optimizing / interpreting avoids this. Fortunately, a modern JVM / debug agent can do this "on the fly" as required.






share|improve this answer


























  • Thanks man, There is another ambiguous point. When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep? I guess when interrupt Thread1 with sleep when it back to continue it will use fresh value of test. Am I right?

    – Spara
    Dec 29 '18 at 8:42
















7















As I expected, since boolean test is not volatile Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything.




Your expectation is incorrect.



According to the Java Language Specification, if one thread updates a non-volatile shared variable and another thread subsequently reads it without appropriate synchronization then the second thread may see the new value, or it may see an earlier value.



So what you are seeing is allowed by the JLS.





In practice, when a debug agent is attached to a JVM, it will typically JIT compile methods at a lower optimization level ... or execute them using the bytecode interpreter. This is likely to happen for methods with breakpoints set in them, and when you are single-stepping1. This may result in different behavior for code that uses shared variables without proper synchronization when you debug it.



This is one of the reasons that debugging problems caused by inadequate synchronization is difficult.






As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?




That is what happens when you debug C / C++. It is not specified how a JVM handles this, but a typical JVM has other options for implementing breakpoints ... because of bytecodes and JIT compilation.






When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep?




The sleep will cause the current thread to be suspended. What happens at the implementation level is not specified. However, it is likely that the native thread mechanisms will flush any outstanding writes (i.e. dirty cache entries) for the suspended thread to memory ... as part of the process of performing a thread context switch.



Similarly, if you use print statements, a typical I/O stack has internal synchronization that can trigger cache flushes, etc. This can also alter the behavior of the code that you are trying to debug.



However, I should stress that these behaviors are not specified.





1 - A JIT optimizer is allowed to reorder assignments provided that this doesn't alter single-threaded behavior. But, if you are debugging a method and observing that values of variables, the effects of the reordering are visible (to the programmer). De-optimizing / interpreting avoids this. Fortunately, a modern JVM / debug agent can do this "on the fly" as required.






share|improve this answer


























  • Thanks man, There is another ambiguous point. When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep? I guess when interrupt Thread1 with sleep when it back to continue it will use fresh value of test. Am I right?

    – Spara
    Dec 29 '18 at 8:42














7












7








7








As I expected, since boolean test is not volatile Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything.




Your expectation is incorrect.



According to the Java Language Specification, if one thread updates a non-volatile shared variable and another thread subsequently reads it without appropriate synchronization then the second thread may see the new value, or it may see an earlier value.



So what you are seeing is allowed by the JLS.





In practice, when a debug agent is attached to a JVM, it will typically JIT compile methods at a lower optimization level ... or execute them using the bytecode interpreter. This is likely to happen for methods with breakpoints set in them, and when you are single-stepping1. This may result in different behavior for code that uses shared variables without proper synchronization when you debug it.



This is one of the reasons that debugging problems caused by inadequate synchronization is difficult.






As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?




That is what happens when you debug C / C++. It is not specified how a JVM handles this, but a typical JVM has other options for implementing breakpoints ... because of bytecodes and JIT compilation.






When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep?




The sleep will cause the current thread to be suspended. What happens at the implementation level is not specified. However, it is likely that the native thread mechanisms will flush any outstanding writes (i.e. dirty cache entries) for the suspended thread to memory ... as part of the process of performing a thread context switch.



Similarly, if you use print statements, a typical I/O stack has internal synchronization that can trigger cache flushes, etc. This can also alter the behavior of the code that you are trying to debug.



However, I should stress that these behaviors are not specified.





1 - A JIT optimizer is allowed to reorder assignments provided that this doesn't alter single-threaded behavior. But, if you are debugging a method and observing that values of variables, the effects of the reordering are visible (to the programmer). De-optimizing / interpreting avoids this. Fortunately, a modern JVM / debug agent can do this "on the fly" as required.






share|improve this answer
















As I expected, since boolean test is not volatile Thread1 uses local cache value of test and when Thread2 changes it to true Thread1 won't do anything.




Your expectation is incorrect.



According to the Java Language Specification, if one thread updates a non-volatile shared variable and another thread subsequently reads it without appropriate synchronization then the second thread may see the new value, or it may see an earlier value.



So what you are seeing is allowed by the JLS.





In practice, when a debug agent is attached to a JVM, it will typically JIT compile methods at a lower optimization level ... or execute them using the bytecode interpreter. This is likely to happen for methods with breakpoints set in them, and when you are single-stepping1. This may result in different behavior for code that uses shared variables without proper synchronization when you debug it.



This is one of the reasons that debugging problems caused by inadequate synchronization is difficult.






As far as I know breakpoints change the instructions of code by adding a special trap called INT 3. So what's really going on?




That is what happens when you debug C / C++. It is not specified how a JVM handles this, but a typical JVM has other options for implementing breakpoints ... because of bytecodes and JIT compilation.






When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep?




The sleep will cause the current thread to be suspended. What happens at the implementation level is not specified. However, it is likely that the native thread mechanisms will flush any outstanding writes (i.e. dirty cache entries) for the suspended thread to memory ... as part of the process of performing a thread context switch.



Similarly, if you use print statements, a typical I/O stack has internal synchronization that can trigger cache flushes, etc. This can also alter the behavior of the code that you are trying to debug.



However, I should stress that these behaviors are not specified.





1 - A JIT optimizer is allowed to reorder assignments provided that this doesn't alter single-threaded behavior. But, if you are debugging a method and observing that values of variables, the effects of the reordering are visible (to the programmer). De-optimizing / interpreting avoids this. Fortunately, a modern JVM / debug agent can do this "on the fly" as required.







share|improve this answer














share|improve this answer



share|improve this answer








edited Dec 29 '18 at 22:02

























answered Dec 29 '18 at 8:13









Stephen CStephen C

515k69563920




515k69563920













  • Thanks man, There is another ambiguous point. When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep? I guess when interrupt Thread1 with sleep when it back to continue it will use fresh value of test. Am I right?

    – Spara
    Dec 29 '18 at 8:42



















  • Thanks man, There is another ambiguous point. When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep? I guess when interrupt Thread1 with sleep when it back to continue it will use fresh value of test. Am I right?

    – Spara
    Dec 29 '18 at 8:42

















Thanks man, There is another ambiguous point. When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep? I guess when interrupt Thread1 with sleep when it back to continue it will use fresh value of test. Am I right?

– Spara
Dec 29 '18 at 8:42





Thanks man, There is another ambiguous point. When I put a sleep(1) in the Thread1 before if statement it will also print the line. Is there a same thing happening by adding a sleep? I guess when interrupt Thread1 with sleep when it back to continue it will use fresh value of test. Am I right?

– Spara
Dec 29 '18 at 8:42













4














Warning: this answer is based mostly on how .Net debuggers work but I expect similar behavior between two runtimes. I expect JVM to allow per-method re-JIT-ing at run time as it already can replace method with HotSpot JIT.



There is some existing articles and posts about what optimizations are turned off for debugging like AMD: perf when debugging enabled, Side Effects of running the JVM in debug mode, Will Java app slow down by presence of -Xdebug or only when stepping through code?. They hint that at least when there is an exception code takes significantly different code path under debugger which may be how breakpoints are implemented.





Many debuggers turn off optimizations (compile time if you allow to recompile code and JIT time if you debugging existing code) when you debug the code. In .Net world impact is global - when debugger is attached it can switch all future JIT compilations to non-optimized path, I expect Java/JVM to support more granular control to allow de-optimizing only methods that may need to stop in debugger. This is done to allow you to clearly see all values of all variables. Otherwise half of the information sometimes including method calls and local/member variables is not available.



"uses local cache value of test" is optimization (likely at JIT time) - so when you start debugging the code (or enable some sort of step-through with breakpoints) it will switch off optimization and read from memory every time thus essentially making variable close to volatile (still not necessary to behave that way all the time but close).



Depending on debugger you use you may disable such behavior (but debugging will be much harder).






share|improve this answer


























  • Thanks for your answer, But It will not print on debugging mode, It will just print when I put the breakpoint, And when I remove the breakpoint it will not print anymore!

    – Spara
    Dec 28 '18 at 22:02











  • @Spara I expect Java debuggers to be smarter than .Net once (which I really based my answer on) and re-JIT single method when you want to add breakpoint in one. Try to disable optimizations (stackoverflow.com/questions/5242405/…) and see if you get the same behavior you get with the breakpoint.

    – Alexei Levenkov
    Dec 28 '18 at 22:07













  • With disabling optimization there will be no thread caches and so it will always print the line with or without a breakpoint

    – Spara
    Dec 28 '18 at 22:09






  • 1





    @Spara yes, that's what I believe happens - when you want to step-through a method it had to be de-optimized and would behave the same way as if there were no optimizations enabled in a first place. The only info I found about JVM's behavior talk about de-optimizing code throwing exceptions - so you need a JVM+JVMTI+JDI expert to answer this for real. I'd recommend adding bounty when you can.

    – Alexei Levenkov
    Dec 29 '18 at 1:36






  • 1





    @Spara side note: I'd be very concern about writing code that explicitly relies on run-time optimization behavior (I assume you just have this as an example of strange behavior and not something you actually use in production).

    – Alexei Levenkov
    Dec 29 '18 at 1:37
















4














Warning: this answer is based mostly on how .Net debuggers work but I expect similar behavior between two runtimes. I expect JVM to allow per-method re-JIT-ing at run time as it already can replace method with HotSpot JIT.



There is some existing articles and posts about what optimizations are turned off for debugging like AMD: perf when debugging enabled, Side Effects of running the JVM in debug mode, Will Java app slow down by presence of -Xdebug or only when stepping through code?. They hint that at least when there is an exception code takes significantly different code path under debugger which may be how breakpoints are implemented.





Many debuggers turn off optimizations (compile time if you allow to recompile code and JIT time if you debugging existing code) when you debug the code. In .Net world impact is global - when debugger is attached it can switch all future JIT compilations to non-optimized path, I expect Java/JVM to support more granular control to allow de-optimizing only methods that may need to stop in debugger. This is done to allow you to clearly see all values of all variables. Otherwise half of the information sometimes including method calls and local/member variables is not available.



"uses local cache value of test" is optimization (likely at JIT time) - so when you start debugging the code (or enable some sort of step-through with breakpoints) it will switch off optimization and read from memory every time thus essentially making variable close to volatile (still not necessary to behave that way all the time but close).



Depending on debugger you use you may disable such behavior (but debugging will be much harder).






share|improve this answer


























  • Thanks for your answer, But It will not print on debugging mode, It will just print when I put the breakpoint, And when I remove the breakpoint it will not print anymore!

    – Spara
    Dec 28 '18 at 22:02











  • @Spara I expect Java debuggers to be smarter than .Net once (which I really based my answer on) and re-JIT single method when you want to add breakpoint in one. Try to disable optimizations (stackoverflow.com/questions/5242405/…) and see if you get the same behavior you get with the breakpoint.

    – Alexei Levenkov
    Dec 28 '18 at 22:07













  • With disabling optimization there will be no thread caches and so it will always print the line with or without a breakpoint

    – Spara
    Dec 28 '18 at 22:09






  • 1





    @Spara yes, that's what I believe happens - when you want to step-through a method it had to be de-optimized and would behave the same way as if there were no optimizations enabled in a first place. The only info I found about JVM's behavior talk about de-optimizing code throwing exceptions - so you need a JVM+JVMTI+JDI expert to answer this for real. I'd recommend adding bounty when you can.

    – Alexei Levenkov
    Dec 29 '18 at 1:36






  • 1





    @Spara side note: I'd be very concern about writing code that explicitly relies on run-time optimization behavior (I assume you just have this as an example of strange behavior and not something you actually use in production).

    – Alexei Levenkov
    Dec 29 '18 at 1:37














4












4








4







Warning: this answer is based mostly on how .Net debuggers work but I expect similar behavior between two runtimes. I expect JVM to allow per-method re-JIT-ing at run time as it already can replace method with HotSpot JIT.



There is some existing articles and posts about what optimizations are turned off for debugging like AMD: perf when debugging enabled, Side Effects of running the JVM in debug mode, Will Java app slow down by presence of -Xdebug or only when stepping through code?. They hint that at least when there is an exception code takes significantly different code path under debugger which may be how breakpoints are implemented.





Many debuggers turn off optimizations (compile time if you allow to recompile code and JIT time if you debugging existing code) when you debug the code. In .Net world impact is global - when debugger is attached it can switch all future JIT compilations to non-optimized path, I expect Java/JVM to support more granular control to allow de-optimizing only methods that may need to stop in debugger. This is done to allow you to clearly see all values of all variables. Otherwise half of the information sometimes including method calls and local/member variables is not available.



"uses local cache value of test" is optimization (likely at JIT time) - so when you start debugging the code (or enable some sort of step-through with breakpoints) it will switch off optimization and read from memory every time thus essentially making variable close to volatile (still not necessary to behave that way all the time but close).



Depending on debugger you use you may disable such behavior (but debugging will be much harder).






share|improve this answer















Warning: this answer is based mostly on how .Net debuggers work but I expect similar behavior between two runtimes. I expect JVM to allow per-method re-JIT-ing at run time as it already can replace method with HotSpot JIT.



There is some existing articles and posts about what optimizations are turned off for debugging like AMD: perf when debugging enabled, Side Effects of running the JVM in debug mode, Will Java app slow down by presence of -Xdebug or only when stepping through code?. They hint that at least when there is an exception code takes significantly different code path under debugger which may be how breakpoints are implemented.





Many debuggers turn off optimizations (compile time if you allow to recompile code and JIT time if you debugging existing code) when you debug the code. In .Net world impact is global - when debugger is attached it can switch all future JIT compilations to non-optimized path, I expect Java/JVM to support more granular control to allow de-optimizing only methods that may need to stop in debugger. This is done to allow you to clearly see all values of all variables. Otherwise half of the information sometimes including method calls and local/member variables is not available.



"uses local cache value of test" is optimization (likely at JIT time) - so when you start debugging the code (or enable some sort of step-through with breakpoints) it will switch off optimization and read from memory every time thus essentially making variable close to volatile (still not necessary to behave that way all the time but close).



Depending on debugger you use you may disable such behavior (but debugging will be much harder).







share|improve this answer














share|improve this answer



share|improve this answer








edited Dec 29 '18 at 1:38

























answered Dec 28 '18 at 21:58









Alexei LevenkovAlexei Levenkov

84.2k890132




84.2k890132













  • Thanks for your answer, But It will not print on debugging mode, It will just print when I put the breakpoint, And when I remove the breakpoint it will not print anymore!

    – Spara
    Dec 28 '18 at 22:02











  • @Spara I expect Java debuggers to be smarter than .Net once (which I really based my answer on) and re-JIT single method when you want to add breakpoint in one. Try to disable optimizations (stackoverflow.com/questions/5242405/…) and see if you get the same behavior you get with the breakpoint.

    – Alexei Levenkov
    Dec 28 '18 at 22:07













  • With disabling optimization there will be no thread caches and so it will always print the line with or without a breakpoint

    – Spara
    Dec 28 '18 at 22:09






  • 1





    @Spara yes, that's what I believe happens - when you want to step-through a method it had to be de-optimized and would behave the same way as if there were no optimizations enabled in a first place. The only info I found about JVM's behavior talk about de-optimizing code throwing exceptions - so you need a JVM+JVMTI+JDI expert to answer this for real. I'd recommend adding bounty when you can.

    – Alexei Levenkov
    Dec 29 '18 at 1:36






  • 1





    @Spara side note: I'd be very concern about writing code that explicitly relies on run-time optimization behavior (I assume you just have this as an example of strange behavior and not something you actually use in production).

    – Alexei Levenkov
    Dec 29 '18 at 1:37



















  • Thanks for your answer, But It will not print on debugging mode, It will just print when I put the breakpoint, And when I remove the breakpoint it will not print anymore!

    – Spara
    Dec 28 '18 at 22:02











  • @Spara I expect Java debuggers to be smarter than .Net once (which I really based my answer on) and re-JIT single method when you want to add breakpoint in one. Try to disable optimizations (stackoverflow.com/questions/5242405/…) and see if you get the same behavior you get with the breakpoint.

    – Alexei Levenkov
    Dec 28 '18 at 22:07













  • With disabling optimization there will be no thread caches and so it will always print the line with or without a breakpoint

    – Spara
    Dec 28 '18 at 22:09






  • 1





    @Spara yes, that's what I believe happens - when you want to step-through a method it had to be de-optimized and would behave the same way as if there were no optimizations enabled in a first place. The only info I found about JVM's behavior talk about de-optimizing code throwing exceptions - so you need a JVM+JVMTI+JDI expert to answer this for real. I'd recommend adding bounty when you can.

    – Alexei Levenkov
    Dec 29 '18 at 1:36






  • 1





    @Spara side note: I'd be very concern about writing code that explicitly relies on run-time optimization behavior (I assume you just have this as an example of strange behavior and not something you actually use in production).

    – Alexei Levenkov
    Dec 29 '18 at 1:37

















Thanks for your answer, But It will not print on debugging mode, It will just print when I put the breakpoint, And when I remove the breakpoint it will not print anymore!

– Spara
Dec 28 '18 at 22:02





Thanks for your answer, But It will not print on debugging mode, It will just print when I put the breakpoint, And when I remove the breakpoint it will not print anymore!

– Spara
Dec 28 '18 at 22:02













@Spara I expect Java debuggers to be smarter than .Net once (which I really based my answer on) and re-JIT single method when you want to add breakpoint in one. Try to disable optimizations (stackoverflow.com/questions/5242405/…) and see if you get the same behavior you get with the breakpoint.

– Alexei Levenkov
Dec 28 '18 at 22:07







@Spara I expect Java debuggers to be smarter than .Net once (which I really based my answer on) and re-JIT single method when you want to add breakpoint in one. Try to disable optimizations (stackoverflow.com/questions/5242405/…) and see if you get the same behavior you get with the breakpoint.

– Alexei Levenkov
Dec 28 '18 at 22:07















With disabling optimization there will be no thread caches and so it will always print the line with or without a breakpoint

– Spara
Dec 28 '18 at 22:09





With disabling optimization there will be no thread caches and so it will always print the line with or without a breakpoint

– Spara
Dec 28 '18 at 22:09




1




1





@Spara yes, that's what I believe happens - when you want to step-through a method it had to be de-optimized and would behave the same way as if there were no optimizations enabled in a first place. The only info I found about JVM's behavior talk about de-optimizing code throwing exceptions - so you need a JVM+JVMTI+JDI expert to answer this for real. I'd recommend adding bounty when you can.

– Alexei Levenkov
Dec 29 '18 at 1:36





@Spara yes, that's what I believe happens - when you want to step-through a method it had to be de-optimized and would behave the same way as if there were no optimizations enabled in a first place. The only info I found about JVM's behavior talk about de-optimizing code throwing exceptions - so you need a JVM+JVMTI+JDI expert to answer this for real. I'd recommend adding bounty when you can.

– Alexei Levenkov
Dec 29 '18 at 1:36




1




1





@Spara side note: I'd be very concern about writing code that explicitly relies on run-time optimization behavior (I assume you just have this as an example of strange behavior and not something you actually use in production).

– Alexei Levenkov
Dec 29 '18 at 1:37





@Spara side note: I'd be very concern about writing code that explicitly relies on run-time optimization behavior (I assume you just have this as an example of strange behavior and not something you actually use in production).

– Alexei Levenkov
Dec 29 '18 at 1:37











1














When you run code, it goes through a couple of stages of optimisation. Initially it is interpreted and your boolean variable might be consistently visible, however at the highest level of optimisation, the value can be inlined (not just cached) and you never see the change. The point at which this happens depends on how many times the code has looped and when the code is compiled and replaced in the background.



When you add logging or break points or sleep(1) you slow down the application and takes longer to reach the threshold at which the code is optimised. This means you avoid seeing the issue esp if it's a race condition.






share|improve this answer
























  • So you mean by slowing down the application, Optimization would not do anything?

    – Spara
    Dec 29 '18 at 9:05











  • I added for (int i = 0 ; i < Integer.MAX_VALUE; i++); at top of if statement in Thread1 and it printed the line. So it seems if the threshold passes JVM would not optimize the thread.

    – Spara
    Dec 29 '18 at 10:58











  • @Spara this loop will trigger the method to be compiled based on the runtime information it has (i.e. for the rest of the code none as it hasn't run it)

    – Peter Lawrey
    Dec 29 '18 at 20:43
















1














When you run code, it goes through a couple of stages of optimisation. Initially it is interpreted and your boolean variable might be consistently visible, however at the highest level of optimisation, the value can be inlined (not just cached) and you never see the change. The point at which this happens depends on how many times the code has looped and when the code is compiled and replaced in the background.



When you add logging or break points or sleep(1) you slow down the application and takes longer to reach the threshold at which the code is optimised. This means you avoid seeing the issue esp if it's a race condition.






share|improve this answer
























  • So you mean by slowing down the application, Optimization would not do anything?

    – Spara
    Dec 29 '18 at 9:05











  • I added for (int i = 0 ; i < Integer.MAX_VALUE; i++); at top of if statement in Thread1 and it printed the line. So it seems if the threshold passes JVM would not optimize the thread.

    – Spara
    Dec 29 '18 at 10:58











  • @Spara this loop will trigger the method to be compiled based on the runtime information it has (i.e. for the rest of the code none as it hasn't run it)

    – Peter Lawrey
    Dec 29 '18 at 20:43














1












1








1







When you run code, it goes through a couple of stages of optimisation. Initially it is interpreted and your boolean variable might be consistently visible, however at the highest level of optimisation, the value can be inlined (not just cached) and you never see the change. The point at which this happens depends on how many times the code has looped and when the code is compiled and replaced in the background.



When you add logging or break points or sleep(1) you slow down the application and takes longer to reach the threshold at which the code is optimised. This means you avoid seeing the issue esp if it's a race condition.






share|improve this answer













When you run code, it goes through a couple of stages of optimisation. Initially it is interpreted and your boolean variable might be consistently visible, however at the highest level of optimisation, the value can be inlined (not just cached) and you never see the change. The point at which this happens depends on how many times the code has looped and when the code is compiled and replaced in the background.



When you add logging or break points or sleep(1) you slow down the application and takes longer to reach the threshold at which the code is optimised. This means you avoid seeing the issue esp if it's a race condition.







share|improve this answer












share|improve this answer



share|improve this answer










answered Dec 29 '18 at 8:54









Peter LawreyPeter Lawrey

442k56559965




442k56559965













  • So you mean by slowing down the application, Optimization would not do anything?

    – Spara
    Dec 29 '18 at 9:05











  • I added for (int i = 0 ; i < Integer.MAX_VALUE; i++); at top of if statement in Thread1 and it printed the line. So it seems if the threshold passes JVM would not optimize the thread.

    – Spara
    Dec 29 '18 at 10:58











  • @Spara this loop will trigger the method to be compiled based on the runtime information it has (i.e. for the rest of the code none as it hasn't run it)

    – Peter Lawrey
    Dec 29 '18 at 20:43



















  • So you mean by slowing down the application, Optimization would not do anything?

    – Spara
    Dec 29 '18 at 9:05











  • I added for (int i = 0 ; i < Integer.MAX_VALUE; i++); at top of if statement in Thread1 and it printed the line. So it seems if the threshold passes JVM would not optimize the thread.

    – Spara
    Dec 29 '18 at 10:58











  • @Spara this loop will trigger the method to be compiled based on the runtime information it has (i.e. for the rest of the code none as it hasn't run it)

    – Peter Lawrey
    Dec 29 '18 at 20:43

















So you mean by slowing down the application, Optimization would not do anything?

– Spara
Dec 29 '18 at 9:05





So you mean by slowing down the application, Optimization would not do anything?

– Spara
Dec 29 '18 at 9:05













I added for (int i = 0 ; i < Integer.MAX_VALUE; i++); at top of if statement in Thread1 and it printed the line. So it seems if the threshold passes JVM would not optimize the thread.

– Spara
Dec 29 '18 at 10:58





I added for (int i = 0 ; i < Integer.MAX_VALUE; i++); at top of if statement in Thread1 and it printed the line. So it seems if the threshold passes JVM would not optimize the thread.

– Spara
Dec 29 '18 at 10:58













@Spara this loop will trigger the method to be compiled based on the runtime information it has (i.e. for the rest of the code none as it hasn't run it)

– Peter Lawrey
Dec 29 '18 at 20:43





@Spara this loop will trigger the method to be compiled based on the runtime information it has (i.e. for the rest of the code none as it hasn't run it)

– Peter Lawrey
Dec 29 '18 at 20:43


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53964510%2fputting-a-breakpoint-in-a-non-reachable-thread-forces-it-to-run%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







OZI2r7HOHKE9Iyk3q,A1t7cQ 5uDiFShe2iV t6kZoV7YW4
17O5u,0jwZs5u72EmOh1b6JHQ64asiUAmI2TsBDHeu1QjVq wJdAzmA,0aAh2yDX aiX4mC8ljn

Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas