<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <br>
    <div class="moz-cite-prefix">On 05/04/2013 01:42 AM, Vitaly
      Davidovich wrote:<br>
    </div>
    <blockquote
cite="mid:CAHjP37FSJhY4RBvFnX-rB9vmfPf2JMEqDVuzJci55_dJhrQymA@mail.gmail.com"
      type="cite"><!--[if !IE]><DIV style="border-left: 2px solid #009900; border-right: 2px solid #009900;  padding: 0px 15px; margin: 2px 0px;"><![endif]-->
      <p dir="ltr">Personally, I think I'd exit the VM in this case. 
        The odds of hitting OOM while allocating TIE and having it be
        just a very unfortunate transient condition are quite low; most
        likely, the VM is going to have lots of trouble elsewhere
        anyway.</p>
      <!--[if !IE]></DIV><![endif]--></blockquote>
    <br>
    I thought the purpose of fixing this bug was exactly to support
    un-terminated reference processing in situations where OOME *is* a
    transient condition, and not to take every opportunity to exit the
    VM when OOME is encountered.<br>
    <br>
    <blockquote
cite="mid:CAHjP37FSJhY4RBvFnX-rB9vmfPf2JMEqDVuzJci55_dJhrQymA@mail.gmail.com"
      type="cite"><!--[if !IE]><DIV style="border-left: 2px solid #009900; border-right: 2px solid #009900;  padding: 0px 15px; margin: 2px 0px;"><![endif]-->
      <p dir="ltr">Also, by swallowing the OOM there and continuing
        makes an assumption that the lock is still in valid/working
        state; that may be the case today, but I don't know if that's a
        safe assumption generally.</p>
      <!--[if !IE]></DIV><![endif]--></blockquote>
    <br>
    I think It would be a JVM bug if it wasn't so. The construction and
    propagation of InterruptedException should be and is attempted after
    the ownership of the object monitor is re-obtained.<br>
    <br>
    Besides, no OOME will be thrown if the ReferenceHandler thread isn't
    interrupted while there is heap memory shortage, but VM is equally
    "in trouble elsewhere" nevertheless. So I don't think it's
    ReferenceHandler's call to decide when to terminate the VM. It can
    continue with it's purpose unaffected...<br>
    <br>
    Another thing to be considered is what happens when the
    ReferenceHandler thread is stop()-ed while it is executing code
    inside wait(). In this case a ThreadDeath is thrown which should not
    be caught and ignored. But as it appears, the ThreadDeath error
    object is constructed by the thread executing the Thread.stop()
    method so the OOME can only be thrown in that thread and not in the
    thread being stopped...<br>
    <br>
    To back this claims, I have written the following test:<br>
    <br>
    <tt>public class Test extends Thread {</tt><tt><br>
    </tt><tt><br>
    </tt><tt>    final Object lock = new Object();</tt><tt><br>
    </tt><tt><br>
    </tt><tt>    public Test() {</tt><tt><br>
    </tt><tt>        super("test");</tt><tt><br>
    </tt><tt>    }</tt><tt><br>
    </tt><tt><br>
    </tt><tt>    static void log(String msg) {</tt><tt><br>
    </tt><tt>        System.err.println(</tt><tt><br>
    </tt><tt>            Thread.currentThread().getName() +</tt><tt><br>
    </tt><tt>            " @ " + new
      SimpleDateFormat("hh:mm:ss.SSS").format(new Date()) +</tt><tt><br>
    </tt><tt>            ": " + msg</tt><tt><br>
    </tt><tt>        );</tt><tt><br>
    </tt><tt>    }</tt><tt><br>
    </tt><tt><br>
    </tt><tt>    @Override</tt><tt><br>
    </tt><tt>    public void run() {</tt><tt><br>
    </tt><tt>        while (true) {</tt><tt><br>
    </tt><tt>            synchronized (lock) {</tt><tt><br>
    </tt><tt>                try {</tt><tt><br>
    </tt><tt>                    log("waiting");</tt><tt><br>
    </tt><tt>                    lock.wait();</tt><tt><br>
    </tt><tt>                }</tt><tt><br>
    </tt><tt>                catch (InterruptedException ie) {</tt><tt><br>
    </tt><tt>                    log("interrupted");</tt><tt><br>
    </tt><tt>                    ie.printStackTrace();</tt><tt><br>
    </tt><tt>                }</tt><tt><br>
    </tt><tt>                catch (ThreadDeath td) {</tt><tt><br>
    </tt><tt>                    log("stopped");</tt><tt><br>
    </tt><tt>                    td.printStackTrace();</tt><tt><br>
    </tt><tt>                    throw td;</tt><tt><br>
    </tt><tt>                }</tt><tt><br>
    </tt><tt>            }</tt><tt><br>
    </tt><tt>        }</tt><tt><br>
    </tt><tt>    }</tt><tt><br>
    </tt><tt><br>
    </tt><tt>    public static void main(String[] args) throws Exception
      {</tt><tt><br>
    </tt><tt>        Test test = new Test();</tt><tt><br>
    </tt><tt>        test.start();</tt><tt><br>
    </tt><tt><br>
    </tt><tt>        Thread.sleep(1000L);</tt><tt><br>
    </tt><tt>        synchronized (test.lock) {</tt><tt><br>
    </tt><tt>            log("interrupting");</tt><tt><br>
    </tt><tt>            test.interrupt();</tt><tt><br>
    </tt><tt>            Thread.sleep(1000L);</tt><tt><br>
    </tt><tt>        }</tt><tt><br>
    </tt><tt>        log("exited synchronized block 1");</tt><tt><br>
    </tt><tt><br>
    </tt><tt>        Thread.sleep(1000L);</tt><tt><br>
    </tt><tt>        synchronized (test.lock) {</tt><tt><br>
    </tt><tt>            log("stopping");</tt><tt><br>
    </tt><tt>            test.stop();</tt><tt><br>
    </tt><tt>            Thread.sleep(1000L);</tt><tt><br>
    </tt><tt>        }</tt><tt><br>
    </tt><tt>        log("exited synchronized block 2");</tt><tt><br>
    </tt><tt><br>
    </tt><tt>        test.join();</tt><tt><br>
    </tt><tt>    }</tt><tt><br>
    </tt><tt>}</tt><br>
    <br>
    <br>
    Which produces the following output:<br>
    <br>
    <tt>test @ 09:57:53.998: waiting</tt><tt><br>
    </tt><tt>main @ 09:57:54.974: interrupting</tt><tt><br>
    </tt><tt>main @ 09:57:55.975: exited synchronized block 1</tt><tt><br>
    </tt><tt>test @ 09:57:55.975: interrupted</tt><tt><br>
    </tt><tt>java.lang.InterruptedException: Constructed by test @
      09:57:55.975</tt><tt><br>
    </tt><tt>    at java.lang.Object.wait(Native Method)</tt><tt><br>
    </tt><tt>    at java.lang.Object.wait(Object.java:502)</tt><tt><br>
    </tt><tt>    at test.Test.run(Test.java:36)</tt><tt><br>
    </tt><tt>test @ 09:57:55.977: waiting</tt><tt><br>
    </tt><tt>main @ 09:57:56.975: stopping</tt><tt><br>
    </tt><tt>main @ 09:57:57.976: exited synchronized block 2</tt><tt><br>
    </tt><tt>test @ 09:57:57.976: stopped</tt><tt><br>
    </tt><tt>java.lang.ThreadDeath: Constructed by main @ 09:57:56.976</tt><tt><br>
    </tt><tt>    at java.lang.Thread.stop(Thread.java:815)</tt><tt><br>
    </tt><tt>    at test.Test.main(Test.java:66)</tt><tt><br>
    </tt><tt><br>
    </tt><br>
    I also modified the InterruptedException and ThreadDeath no-arg
    constructors to record the thread name and time of construction to
    get this output:<br>
    <br>
    <tt>    public InterruptedException() {</tt><tt><br>
    </tt><tt>        super("Constructed by " +
      Thread.currentThread().getName() +</tt><tt><br>
    </tt><tt>              " @ " + new
      SimpleDateFormat("hh:mm:ss.SSS").format(new Date()));</tt><tt><br>
    </tt><tt>    }</tt><br>
    <br>
    <br>
    Regards, Peter<br>
    <br>
    <blockquote
cite="mid:CAHjP37FSJhY4RBvFnX-rB9vmfPf2JMEqDVuzJci55_dJhrQymA@mail.gmail.com"
      type="cite"><!--[if !IE]><DIV style="border-left: 2px solid #009900; border-right: 2px solid #009900;  padding: 0px 15px; margin: 2px 0px;"><![endif]-->
      <p dir="ltr">Sent from my phone</p>
      <div class="gmail_quote">On May 3, 2013 3:26 PM, "Peter Levart"
        <<a moz-do-not-send="true"
          href="mailto:peter.levart@gmail.com">peter.levart@gmail.com</a>>
        wrote:<br type="attribution">
        <blockquote class="gmail_quote" style="margin:0 0 0
          .8ex;border-left:1px #ccc solid;padding-left:1ex">
          <br>
          On 05/03/2013 07:47 PM, Thomas Schatzl wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            Hi,<br>
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">
              Hi Tomas,<br>
              <br>
              I don't know if this is the case here, but what if the<br>
              ReferenceHandler thread is interrupted while wait()-ing
              and the<br>
              construction of InterruptedException triggers OOME?<br>
            </blockquote>
            I am sure this is the case - previously I thought
            InterruptedException<br>
            is a preallocated exception like others.<br>
            ObjectMonitor::wait() may throw it, by creating new
            InterruptedException<br>
            instances.<br>
            <br>
            Thanks!<br>
            <br>
            Now that we've found the very likely cause, what to do about
            it?<br>
          </blockquote>
          <br>
          Maybe just ignore it since if it happens during wait(), the
          cause is supposed to be interrupted thread and the
          InterruptedException that was to be thrown would be ignored
          too:<br>
          <br>
                                  try {<br>
                                      lock.wait();<br>
                                  } catch (InterruptedException |
          OutOfMemoryError x) { }<br>
          <br>
          Regards, Peter<br>
          <br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            The current state of silently crashing the reference handler
            thread is<br>
            unsatisfying imo as it leads to very hard to find problems.<br>
            <br>
            The options I see all involve catching this (or any other
            OOME caused by<br>
            other means like the test program) and either recovering as
            much as<br>
            possible or exiting the VM (like in the sun.misc.Cleaner
            handling).<br>
            <br>
            Any other suggestions?<br>
            <br>
            Thanks,<br>
            Thomas<br>
            <br>
          </blockquote>
          <br>
        </blockquote>
      </div>
      <!--[if !IE]></DIV><![endif]--></blockquote>
    <br>
  </body>
</html>