{"thread":{"id":"18399","subject":"[PATCH JGIT] Method invokes inefficient new String(String) constructor","startedAt":"2009-03-19T09:15:58Z","lastAt":"2009-07-21T19:47:12Z","messageCount":10,"participants":["Yann Simon","Shawn O. Pearce","Robin Rosenberg"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"108495","messageId":"49C20D4E.5020203@gmail.com","threadId":"18399","inReplyTo":null,"subject":"[PATCH JGIT] Method invokes inefficient new String(String) constructor","fromName":"Yann Simon","fromEmail":"yann.simon.fr@gmail.com","sentAt":"2009-03-19T09:15:58Z","receivedAt":"2009-03-19T09:15:58Z","isPatch":true,"sender":{"key":"yann.simon.fr@gmail.com","avatar":"https://gravatar.com/avatar/2d926895d27ac988c5c8e591887e5a6a4c7036390403c74fce92519119b887a0?d=mp&s=160"},"body":">From FindBugs:\nUsing the java.lang.String(String) constructor wastes memory because\nthe object so constructed will be functionally indistinguishable from\nthe String passed as a parameter. Just use the argument String directly.\n\nSigned-off-by: Yann Simon <yann.simon.fr@gmail.com>\n---\n .../src/org/spearce/jgit/lib/RefDatabase.java      |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\nindex 87f26bf..49da538 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n@@ -447,7 +447,7 @@ private synchronized void refreshPackedRefs() {\n \n \t\t\t\t\tfinal int sp = p.indexOf(' ');\n \t\t\t\t\tfinal ObjectId id = ObjectId.fromString(p.substring(0, sp));\n-\t\t\t\t\tfinal String name = new String(p.substring(sp + 1));\n+\t\t\t\t\tfinal String name = p.substring(sp + 1);\n \t\t\t\t\tlast = new Ref(Ref.Storage.PACKED, name, name, id);\n \t\t\t\t\tnewPackedRefs.put(last.getName(), last);\n \t\t\t\t}\n-- \n1.6.1.2\n"},{"id":"108543","messageId":"20090319160102.GQ23521@spearce.org","threadId":"18399","inReplyTo":"49C20D4E.5020203@gmail.com","subject":"Re: [PATCH JGIT] Method invokes inefficient new String(String) constructor","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-03-19T16:01:02Z","receivedAt":"2009-03-19T16:01:02Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Yann Simon <yann.simon.fr@gmail.com> wrote:\n> From FindBugs:\n> Using the java.lang.String(String) constructor wastes memory because\n> the object so constructed will be functionally indistinguishable from\n> the String passed as a parameter. Just use the argument String directly.\n> \n> Signed-off-by: Yann Simon <yann.simon.fr@gmail.com>\n> ---\n>  .../src/org/spearce/jgit/lib/RefDatabase.java      |    2 +-\n>  1 files changed, 1 insertions(+), 1 deletions(-)\n> \n> diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n> index 87f26bf..49da538 100644\n> --- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n> +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n> @@ -447,7 +447,7 @@ private synchronized void refreshPackedRefs() {\n>  \n>  \t\t\t\t\tfinal int sp = p.indexOf(' ');\n>  \t\t\t\t\tfinal ObjectId id = ObjectId.fromString(p.substring(0, sp));\n> -\t\t\t\t\tfinal String name = new String(p.substring(sp + 1));\n> +\t\t\t\t\tfinal String name = p.substring(sp + 1);\n>  \t\t\t\t\tlast = new Ref(Ref.Storage.PACKED, name, name, id);\n>  \t\t\t\t\tnewPackedRefs.put(last.getName(), last);\n\nI had a specific reason for forcing a new String object here.\n\nThe line in question, p, is from the packed-refs file and\ncontains the entire SHA-1 in hex form at the beginning of it.\nWe've converted that into binary as an ObjectId, it uses 1/4 the\nspace of the string portion.\n\nThe Ref object, its ObjectId, and its name string, are going to be\ncached in a Map, probably long-term.  We're better off shedding the\n80 bytes of memory used to hold the hex SHA-1 then risk substring()\ndeciding its \"faster\" to reuse the char[] then to make a copy of it.\n\n-- \nShawn.\n"},{"id":"108547","messageId":"551f769b0903190944ofb03d14u1be316e1dacc1f86@mail.gmail.com","threadId":"18399","inReplyTo":"20090319160102.GQ23521@spearce.org","subject":"Re: [PATCH JGIT] Method invokes inefficient new String(String) constructor","fromName":"Yann Simon","fromEmail":"yann.simon.fr@gmail.com","sentAt":"2009-03-19T16:44:22Z","receivedAt":"2009-03-19T16:44:22Z","isPatch":true,"sender":{"key":"yann.simon.fr@gmail.com","avatar":"https://gravatar.com/avatar/2d926895d27ac988c5c8e591887e5a6a4c7036390403c74fce92519119b887a0?d=mp&s=160"},"body":"2009/3/19 Shawn O. Pearce <spearce@spearce.org>:\n> The line in question, p, is from the packed-refs file and\n> contains the entire SHA-1 in hex form at the beginning of it.\n> We've converted that into binary as an ObjectId, it uses 1/4 the\n> space of the string portion.\n>\n> The Ref object, its ObjectId, and its name string, are going to be\n> cached in a Map, probably long-term.  We're better off shedding the\n> 80 bytes of memory used to hold the hex SHA-1 then risk substring()\n> deciding its \"faster\" to reuse the char[] then to make a copy of it.\n\nThany you for the explanation.\nI learn something, and my tests confirm it.\nThe p.substring(...) can keep the entire array of char by only\nupdating the intern offset value.\nnew String(p.subtring(...)) make sure that the variable contains only\nthe final chars.\n\nYann\n"},{"id":"117663","messageId":"551f769b0907090147x9b78604i77a095441f232703@mail.gmail.com","threadId":"18399","inReplyTo":"20090319160102.GQ23521@spearce.org","subject":"Re: [PATCH JGIT] Method invokes inefficient new String(String) constructor","fromName":"Yann Simon","fromEmail":"yann.simon.fr@gmail.com","sentAt":"2009-07-09T08:47:27Z","receivedAt":"2009-07-09T08:47:27Z","isPatch":true,"sender":{"key":"yann.simon.fr@gmail.com","avatar":"https://gravatar.com/avatar/2d926895d27ac988c5c8e591887e5a6a4c7036390403c74fce92519119b887a0?d=mp&s=160"},"body":"2009/3/19 Shawn O. Pearce <spearce@spearce.org>:\n> Yann Simon <yann.simon.fr@gmail.com> wrote:\n>> From FindBugs:\n>> Using the java.lang.String(String) constructor wastes memory because\n>> the object so constructed will be functionally indistinguishable from\n>> the String passed as a parameter. Just use the argument String directly.\n>>\n>> Signed-off-by: Yann Simon <yann.simon.fr@gmail.com>\n>> ---\n>>  .../src/org/spearce/jgit/lib/RefDatabase.java      |    2 +-\n>>  1 files changed, 1 insertions(+), 1 deletions(-)\n>>\n>> diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n>> index 87f26bf..49da538 100644\n>> --- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n>> +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n>> @@ -447,7 +447,7 @@ private synchronized void refreshPackedRefs() {\n>>\n>>                                       final int sp = p.indexOf(' ');\n>>                                       final ObjectId id = ObjectId.fromString(p.substring(0, sp));\n>> -                                     final String name = new String(p.substring(sp + 1));\n>> +                                     final String name = p.substring(sp + 1);\n>>                                       last = new Ref(Ref.Storage.PACKED, name, name, id);\n>>                                       newPackedRefs.put(last.getName(), last);\n>\n> I had a specific reason for forcing a new String object here.\n>\n> The line in question, p, is from the packed-refs file and\n> contains the entire SHA-1 in hex form at the beginning of it.\n> We've converted that into binary as an ObjectId, it uses 1/4 the\n> space of the string portion.\n>\n> The Ref object, its ObjectId, and its name string, are going to be\n> cached in a Map, probably long-term.  We're better off shedding the\n> 80 bytes of memory used to hold the hex SHA-1 then risk substring()\n> deciding its \"faster\" to reuse the char[] then to make a copy of it.\n\nHowever, using the trick newString = new String(aString.substring(),\ni) does not work on all JVM.\nWith an IBM JVM, the newString will still contain the original array of chars.\n\nAnother solution that work on all JVM could be:\nnewString = new String(aString.substring(i).toCharArray())\nOr\nnewString = new String(aString.toCharArray(), i, aString.length() - i)\n\nI like the latter one.\n\nYann\n"},{"id":"117773","messageId":"20090710153441.GF11191@spearce.org","threadId":"18399","inReplyTo":"551f769b0907090147x9b78604i77a095441f232703@mail.gmail.com","subject":"[PATCH] FindBugs: don't use new String(String) in RefDatabase","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-07-10T15:34:41Z","receivedAt":"2009-07-10T15:34:41Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":">From FindBugs:\n  Using the java.lang.String(String) constructor wastes memory\n  because the object so constructed will be functionally\n  indistinguishable from the String passed as a parameter. Just\n  use the argument String directly.\n\nActually, here we want to get a new String object that covers only\nthe portion of the source string that we are selected out.\n\nThe line in question, p, is from the packed-refs file and contains\nthe entire SHA-1 in hex form at the beginning of it.  We have already\nconverted that into binary as an ObjectId, which uses 1/4 the space\nof the string portion.\n\nThe Ref object, its ObjectId, and its name string, are going to be\ncached in a Map, probably long-term, as the packed-refs file does\nnot change frequently.  We are better off shedding the 80 bytes of\nmemory used to hold the hex SHA-1 then risk substring() deciding its\n\"better\" to reuse the same char[] internally.\n\nBy creating a new StringBuilder of the exact required capacity for\nthe name, and then copying in the region of characters we really\nwant, we defeat the reuse substring() would normally perform, at\nthe tiny cost of an extra StringBuilder temporary.  Some JITs are\nable to stack allocate that here, making it a trivial cost.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\nCC: Yann Simon <yann.simon.fr@gmail.com>\n---\n Yann Simon <yann.simon.fr@gmail.com> wrote:\n > 2009/3/19 Shawn O. Pearce <spearce@spearce.org>:\n > > Yann Simon <yann.simon.fr@gmail.com> wrote:\n > >> From FindBugs:\n > >> Using the java.lang.String(String) constructor wastes [...]\n > \n > However, using the trick newString = new String(aString.substring(),\n > i) does not work on all JVM.\n > With an IBM JVM, the newString will still contain the original array of chars.\n > \n > Another solution that work on all JVM could be:\n > newString = new String(aString.substring(i).toCharArray())\n > Or\n > newString = new String(aString.toCharArray(), i, aString.length() - i)\n > \n > I like the latter one.\n\n I prefer this.  It should always do what we want, and at a lower\n temporary memory footprint (one less copy of the name).  IIRC Robin\n rejected it earlier because it wasn't obvious what we were doing. I\n say hogwash, its clear as mud.\n \n .../src/org/spearce/jgit/lib/RefDatabase.java      |    6 +++++-\n 1 files changed, 5 insertions(+), 1 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\nindex 6d4f374..383877f 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n@@ -438,7 +438,7 @@ private synchronized void refreshPackedRefs() {\n \n \t\t\t\t\tfinal int sp = p.indexOf(' ');\n \t\t\t\t\tfinal ObjectId id = ObjectId.fromString(p.substring(0, sp));\n-\t\t\t\t\tfinal String name = new String(p.substring(sp + 1));\n+\t\t\t\t\tfinal String name = copy(p, sp + 1, p.length());\n \t\t\t\t\tlast = new Ref(Ref.Storage.PACKED, name, name, id);\n \t\t\t\t\tnewPackedRefs.put(last.getName(), last);\n \t\t\t\t}\n@@ -460,6 +460,10 @@ private synchronized void refreshPackedRefs() {\n \t\t}\n \t}\n \n+\tprivate static String copy(final String src, final int off, final int end) {\n+\t\treturn new StringBuilder(end - off).append(src, off, end).toString();\n+\t}\n+\n \tprivate void lockAndWriteFile(File file, byte[] content) throws IOException {\n \t\tString name = file.getName();\n \t\tfinal LockFile lck = new LockFile(file);\n-- \n1.6.3.3.507.gc6b5a\n"},{"id":"117888","messageId":"551f769b0907130107j51d32e4er54e125f9dc61dd80@mail.gmail.com","threadId":"18399","inReplyTo":"20090710153441.GF11191@spearce.org","subject":"Re: [PATCH] FindBugs: don't use new String(String) in RefDatabase","fromName":"Yann Simon","fromEmail":"yann.simon.fr@gmail.com","sentAt":"2009-07-13T08:07:02Z","receivedAt":"2009-07-13T08:07:02Z","isPatch":true,"sender":{"key":"yann.simon.fr@gmail.com","avatar":"https://gravatar.com/avatar/2d926895d27ac988c5c8e591887e5a6a4c7036390403c74fce92519119b887a0?d=mp&s=160"},"body":"2009/7/10 Shawn O. Pearce <spearce@spearce.org>:\n>  Yann Simon <yann.simon.fr@gmail.com> wrote:\n>  >\n>  > However, using the trick newString = new String(aString.substring(),\n>  > i) does not work on all JVM.\n>  > With an IBM JVM, the newString will still contain the original array of chars.\n>  >\n>  > Another solution that work on all JVM could be:\n>  > newString = new String(aString.substring(i).toCharArray())\n>  > Or\n>  > newString = new String(aString.toCharArray(), i, aString.length() - i)\n>  >\n>  > I like the latter one.\n>\n>  I prefer this.  It should always do what we want, and at a lower\n>  temporary memory footprint (one less copy of the name).  IIRC Robin\n>  rejected it earlier because it wasn't obvious what we were doing. I\n>  say hogwash, its clear as mud.\n>\n> +       private static String copy(final String src, final int off, final int end) {\n> +               return new StringBuilder(end - off).append(src, off, end).toString();\n> +       }\n> +\n\nThis method is quite clear.\nOne line javadoc would make it even clearer... :p (and maybe make Robin happy)\n\nAnd you're right: by using a StringBuilder, we need one less arraycopy.\n\nAfter committing your change, we can remove the entry to silent FindBugs.\n(commit 21c3d82824075cd1f140b3bcf252dfaffe0fc96c)\n\nYann\n"},{"id":"117908","messageId":"20090713145308.GI11191@spearce.org","threadId":"18399","inReplyTo":"551f769b0907130107j51d32e4er54e125f9dc61dd80@mail.gmail.com","subject":"[JGIT PATCH v2] FindBugs: don't use new String(String) in RefDatabase","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-07-13T14:53:08Z","receivedAt":"2009-07-13T14:53:08Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":">From FindBugs:\n  Using the java.lang.String(String) constructor wastes memory\n  because the object so constructed will be functionally\n  indistinguishable from the String passed as a parameter. Just\n  use the argument String directly.\n\nActually, here we want to get a new String object that covers only\nthe portion of the source string that we are selected out.\n\nThe line in question, p, is from the packed-refs file and contains\nthe entire SHA-1 in hex form at the beginning of it.  We have already\nconverted that into binary as an ObjectId, which uses 1/4 the space\nof the string portion.\n\nThe Ref object, its ObjectId, and its name string, are going to be\ncached in a Map, probably long-term, as the packed-refs file does\nnot change frequently.  We are better off shedding the 80 bytes of\nmemory used to hold the hex SHA-1 then risk substring() deciding its\n\"better\" to reuse the same char[] internally.\n\nBy creating a new StringBuilder of the exact required capacity for\nthe name, and then copying in the region of characters we really\nwant, we defeat the reuse substring() would normally perform, at\nthe tiny cost of an extra StringBuilder temporary.  Some JITs are\nable to stack allocate that here, making it a trivial cost.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\nCC: Yann Simon <yann.simon.fr@gmail.com>\n---\n Yann Simon <yann.simon.fr@gmail.com> wrote:\n > This method is quite clear.\n > One line javadoc would make it even clearer... :p (and maybe make Robin happy)\n \n Javadoc is overrated.  Private utility methods like this that are one\n line long don't need documentation.  The rationale for why this line\n does what it does is something that `git blame` can answer better.\n  \n > And you're right: by using a StringBuilder, we need one less arraycopy.\n > \n > After committing your change, we can remove the entry to silent FindBugs.\n > (commit 21c3d82824075cd1f140b3bcf252dfaffe0fc96c)\n \n My patch is updated (below).  Thanks, I forgot about that filter.\n\n .../findBugs/FindBugsExcludeFilter.xml             |    7 -------\n .../src/org/spearce/jgit/lib/RefDatabase.java      |    6 +++++-\n 2 files changed, 5 insertions(+), 8 deletions(-)\n\ndiff --git a/org.spearce.jgit/findBugs/FindBugsExcludeFilter.xml b/org.spearce.jgit/findBugs/FindBugsExcludeFilter.xml\nindex 2af9348..a553170 100644\n--- a/org.spearce.jgit/findBugs/FindBugsExcludeFilter.xml\n+++ b/org.spearce.jgit/findBugs/FindBugsExcludeFilter.xml\n@@ -1,12 +1,5 @@\n <?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n <FindBugsFilter>\n-     <!-- Silence inefficient new String(String) constructor warning, see http://thread.gmane.org/gmane.comp.version-control.git/117831/focus=117937 -->\n-     <Match>\n-       <Class name=\"org.spearce.jgit.lib.RefDatabase\" />\n-       <Method name=\"refreshPackedRefs\" />\n-       <Bug pattern=\"DM_STRING_CTOR\" />\n-     </Match>\n-\n      <!-- Silence PackFile.mmap calls GC, we need to force it to remove stale\n           memory mapped segments if the JVM heap is out of address space.\n        -->\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\nindex 6d4f374..383877f 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/RefDatabase.java\n@@ -438,7 +438,7 @@ private synchronized void refreshPackedRefs() {\n \n \t\t\t\t\tfinal int sp = p.indexOf(' ');\n \t\t\t\t\tfinal ObjectId id = ObjectId.fromString(p.substring(0, sp));\n-\t\t\t\t\tfinal String name = new String(p.substring(sp + 1));\n+\t\t\t\t\tfinal String name = copy(p, sp + 1, p.length());\n \t\t\t\t\tlast = new Ref(Ref.Storage.PACKED, name, name, id);\n \t\t\t\t\tnewPackedRefs.put(last.getName(), last);\n \t\t\t\t}\n@@ -460,6 +460,10 @@ private synchronized void refreshPackedRefs() {\n \t\t}\n \t}\n \n+\tprivate static String copy(final String src, final int off, final int end) {\n+\t\treturn new StringBuilder(end - off).append(src, off, end).toString();\n+\t}\n+\n \tprivate void lockAndWriteFile(File file, byte[] content) throws IOException {\n \t\tString name = file.getName();\n \t\tfinal LockFile lck = new LockFile(file);\n-- \n1.6.4.rc0.117.g28cb\n"},{"id":"118369","messageId":"200907211650.36831.robin.rosenberg.lists@dewire.com","threadId":"18399","inReplyTo":"20090713145308.GI11191@spearce.org","subject":"Re: [JGIT PATCH v2] FindBugs: don't use new String(String) in RefDatabase","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg.lists@dewire.com","sentAt":"2009-07-21T14:50:36Z","receivedAt":"2009-07-21T14:50:36Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"måndag 13 juli 2009 16:53:08 skrev \"Shawn O. Pearce\" <spearce@spearce.org>:\n>  Yann Simon <yann.simon.fr@gmail.com> wrote:\n>  > This method is quite clear.\n>  > One line javadoc would make it even clearer... :p (and maybe make Robin happy)\n>  \n>  Javadoc is overrated.  Private utility methods like this that are one\n>  line long don't need documentation.  The rationale for why this line\n>  does what it does is something that `git blame` can answer better.\n\nSorry Yann, I'm with Shawn here. A comment wouldn't add anything here since\nthe method is pretty simple. Besides javadocs are for API's so an inline comment\nwould be better, but I don't think it is necessary.\n\nShawn, any references for the ability of JIT's abilities to stack allocate in this context? For\nme learning, will commit anyway.\n\n-- robina\n"},{"id":"118370","messageId":"20090721150337.GP11191@spearce.org","threadId":"18399","inReplyTo":"200907211650.36831.robin.rosenberg.lists@dewire.com","subject":"Re: [JGIT PATCH v2] FindBugs: don't use new String(String) in RefDatabase","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-07-21T15:03:37Z","receivedAt":"2009-07-21T15:03:37Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Robin Rosenberg <robin.rosenberg.lists@dewire.com> wrote:\n> Shawn, any references for the ability of JIT's abilities to stack allocate in this context? For\n> me learning, will commit anyway.\n\nSee [1] for example.  I read a presentation from a HotSpot engineer\nat Sun a year or two ago that talked about it as a feature in the\nSun Java 6 runtime, but I can't track that down now.\n\nIts a pretty simple concept.  Folks realized that some types,\ne.g. StringBuilder, are often used only within a single stack\nframe, and that escape analysis can be used to prove that the\nStringBuilder instance is only visible within that stack frame.\nDoing a stack allocation instead of a heap allocation would allow\nthe JVM to avoid creating unnecessary garbage.\n\nAh, according to [2] the feature is only in 6u14 and later, and is\nan option you still need to enable on the command line.  But its\nthe direction the Sun JVM is going.  I imagine it would be on by\ndefault in the future, various performance tests seem to indicate\nits a worthwhile optimization.\n\n[1] http://www.ibm.com/developerworks/java/library/j-jtp09275.html?ca=dgr-lnxw01JavaUrbanLegends\n[2] http://java.sun.com/javase/6/webnotes/6u14.html\n\n-- \nShawn.\n"},{"id":"118397","messageId":"200907212147.12878.robin.rosenberg.lists@dewire.com","threadId":"18399","inReplyTo":"20090721150337.GP11191@spearce.org","subject":"Re: [JGIT PATCH v2] FindBugs: don't use new String(String) in RefDatabase","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg.lists@dewire.com","sentAt":"2009-07-21T19:47:12Z","receivedAt":"2009-07-21T19:47:12Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"tisdag 21 juli 2009 17:03:37 skrev \"Shawn O. Pearce\" <spearce@spearce.org>:\n> Robin Rosenberg <robin.rosenberg.lists@dewire.com> wrote:\n> > Shawn, any references for the ability of JIT's abilities to stack allocate in this context? For\n> > me learning, will commit anyway.\n> \n> See [1] for example.  I read a presentation from a HotSpot engineer\n> at Sun a year or two ago that talked about it as a feature in the\n> Sun Java 6 runtime, but I can't track that down now.\n>\n...\n> \n> [1] http://www.ibm.com/developerworks/java/library/j-jtp09275.html?ca=dgr-lnxw01JavaUrbanLegends\n> [2] http://java.sun.com/javase/6/webnotes/6u14.html\n> \n\nThanks. HotSpot rules.\n\n-- robin\n"}]}