Index: jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameFactoryImpl.java
===================================================================
--- jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameFactoryImpl.java	(revision 671986)
+++ jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameFactoryImpl.java	(working copy)
@@ -26,6 +26,18 @@
 
     private static final NameFactory INSTANCE = new NameFactoryImpl();
 
+    /**
+     * Hashed array of flyweight name instances. Used to avoid too many
+     * duplicate copies of frequently used names. Note that it's possible
+     * and even probable that some distinct names hash to the same position
+     * in the array, but in practice that should not be a problem. The main
+     * benefit over a more complex solution like an LRUMap is that this
+     * approach requires no synchronization.
+     *
+     * @see https://issues.apache.org/jira/browse/JCR-1663
+     */
+    private final Name[] names = new Name[1024];
+
     private NameFactoryImpl() {};
 
     public static NameFactory getInstance() {
@@ -44,7 +56,7 @@
         if (localName == null) {
             throw new IllegalArgumentException("invalid localName specified");
         }
-        return new NameImpl(namespaceURI, localName);
+        return getName(namespaceURI, localName);
     }
 
     /**
@@ -64,10 +76,32 @@
         if (i == nameString.length() - 1) {
             throw new IllegalArgumentException("Invalid Name literal");
         } else {
-            return new NameImpl(nameString.substring(1, i), nameString.substring(i + 1));
+            return getName(nameString.substring(1, i), nameString.substring(i + 1));
         }
     }
 
+    /**
+     * Returns a name instance for the given namespace URI and local name.
+     * If the name already exists in the hashed {@link #names} array, then
+     * that instance is used to avoid duplicates. Otherwise a new name
+     * instance is stored in the hashed array and returned.
+     *
+     * @param uri namespace URI
+     * @param local local name
+     * @return name instance
+     */
+    private Name getName(String uri, String local) {
+        Name name = new NameImpl(uri, local);
+        int position = Math.abs(name.hashCode()) % names.length;
+        Name prev = names[position];
+        if (name.equals(prev)) {
+            return prev;
+        } else { 
+            names[position] = name;
+            return name;
+        }
+    }
+
     //--------------------------------------------------------< inner class >---
     /**
      * Inner class implementing the <code>Name</code> interface.
