Re: JavaMemoryModel: String literals and String.intern()

From: Doron Rajwan (doron@rajwan.org)
Date: Sat Apr 17 2004 - 15:51:13 EDT


It is possible to know exactly when the GC collects
interned Strings, using System.identityHashCode(). See
the following code:

public class Test {
    public static void tt() {
        String s = "aa".concat("bb").intern();
        System.out.println("code=" + s.hashCode() + ";
sys=" + System.identityHashCode(s));
    }
    public static void main(String[] args) throws
Exception {
        tt(); // code=2986080; sys=17237886
        tt(); // code=2986080; sys=17237886
        System.gc();
        tt(); // code=2986080; sys=28050664
        tt(); // code=2986080; sys=28050664
    }
}

Doron.

--- Thomas Hawtin <thawtin@tackline.demon.co.uk>
wrote:
> Eliot Moss wrote:
> >>>>>>"Doron" == Doron Rajwan <doron@rajwan.org>
> writes:
> >
> > Doron> Thread 1, Thread 2:
> > Doron> synchronized ("some string") {
> > Doron> ++a;
> > Doron> }
> > [...]
> > Doron> 2. However, it is possible that the
> first thread
> > Doron> finished, the GC collected the interned
> string, and
> > Doron> then, the second thread started. In
> this case, the
> > Doron> sync was on a different instance of the
> String.
> >
> > Doron, I don't get what you're saying. Even a
> copying GC has to preserve
> > identity semantics in the face of locking objects.
> And so far as I know, an
> > interned string will never be reclaimed anyway.
>
> Interned Strings behave as normal garbage (if
> somewhat slower to be
> collected than more typical objects). Early Sun JREs
> (1.0 and 1.1)
> failed to collect interned Strings.
>
>
http://developer.java.sun.com/developer/bugParade/bugs/4035345.html
>
http://developer.java.sun.com/developer/bugParade/bugs/1240681.html
>
> In the case above, the class' Class will have a
> reference to the String.
> The Class cannot disappear while the method is
> executing. Therefore,
> there is no data race. However you can easily create
> a race using
>
> synchronized ("some
> ".concat("string").intern()) {
>
> which would be your own fault.
>
> So synchronising an interned String remains a
> working way to achieve a
> process global critical section. Synchronising on a
> StringBuffer, say,
> assigned to a static final field works for a class'
> class loader global
> scoped critical section.
>
> Tom Hawtin
>
> -------------------------------
> JavaMemoryModel mailing list -
http://www.cs.umd.edu/~pugh/java/memoryModel

=====
Doron Rajwan, mailto:doron@rajwan.org

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:01:05 EDT