diff --git a/core/java/src/freenet/support/CPUInformation/CPUID.java b/core/java/src/freenet/support/CPUInformation/CPUID.java
index 921f497ddedb924f5f776e44c865c59fb8bfa79a..3d9c8fe240629f32fc7cece010d29809e5bef4ba 100644
--- a/core/java/src/freenet/support/CPUInformation/CPUID.java
+++ b/core/java/src/freenet/support/CPUInformation/CPUID.java
@@ -45,19 +45,35 @@ public class CPUID {
     private static boolean _doLog = System.getProperty("jcpuid.dontLog") == null &&
                                     I2PAppContext.getGlobalContext().isRouterContext();
 
-    //.matches() is a java 1.4+ addition, using a simplified version for 1.3+
-    //private static final boolean isX86 = System.getProperty("os.arch").toLowerCase().matches("i?[x0-9]86(_64)?");
-    private static final boolean isX86 = (-1 != System.getProperty("os.arch").indexOf("86"));
+    private static final boolean isX86 = System.getProperty("os.arch").contains("86");
     private static final String libPrefix = (System.getProperty("os.name").startsWith("Win") ? "" : "lib");
     private static final String libSuffix = (System.getProperty("os.name").startsWith("Win") ? ".dll" : ".so");
+    private static final boolean isWindows = System.getProperty("os.name").toLowerCase().contains("windows");
+    private static final boolean isLinux = System.getProperty("os.name").toLowerCase().contains("linux");
+    private static final boolean isFreebsd = System.getProperty("os.name").toLowerCase().contains("freebsd");
     
+    /**
+     * This isn't always correct.
+     * http://stackoverflow.com/questions/807263/how-do-i-detect-which-kind-of-jre-is-installed-32bit-vs-64bit
+     * http://mark.koli.ch/2009/10/javas-osarch-system-property-is-the-bitness-of-the-jre-not-the-operating-system.html
+     * http://mark.koli.ch/2009/10/reliably-checking-os-bitness-32-or-64-bit-on-windows-with-a-tiny-c-app.html
+     * sun.arch.data.model not on all JVMs
+     * sun.arch.data.model == 64 => 64 bit processor
+     * sun.arch.data.model == 32 => A 32 bit JVM but could be either 32 or 64 bit processor or libs
+     * os.arch contains "64" could be 32 or 64 bit libs
+     */
+    private static final boolean is64 = "64".equals(System.getProperty("sun.arch.data.model")) ||
+                                        System.getProperty("os.arch").contains("64");
+
     static
     {
         loadNative();
     }
     
-    //A class that can (amongst other things I assume) represent the state of the
-    //different CPU registers after a call to the CPUID assembly method
+    /**
+     * A class that can (amongst other things I assume) represent the state of the
+     * different CPU registers after a call to the CPUID assembly method
+     */
     protected static class CPUIDResult {
         final int EAX;
         final int EBX;
@@ -151,12 +167,14 @@ public class CPUID {
         return c.ECX;
     }
     
-    //Returns a CPUInfo item for the current type of CPU
-    //If I could I would declare this method in a interface named
-    //CPUInfoProvider and implement that interface in this class.
-    //This would make it easier for other people to understand that there
-    //is nothing preventing them from coding up new providers, probably using
-    //other detection methods than the x86-only CPUID instruction
+    /**
+     * Returns a CPUInfo item for the current type of CPU
+     * If I could I would declare this method in a interface named
+     * CPUInfoProvider and implement that interface in this class.
+     * This would make it easier for other people to understand that there
+     * is nothing preventing them from coding up new providers, probably using
+     * other detection methods than the x86-only CPUID instruction
+     */
     public static CPUInfo getInfo() throws UnknownCPUException
     {
         if(!_nativeOk)
@@ -506,7 +524,7 @@ public class CPUID {
         
     }
     
-       /**
+    /**
      * <p>Do whatever we can to load up the native library.
      * If it can find a custom built jcpuid.dll / libjcpuid.so, it'll use that.  Otherwise
      * it'll try to look in the classpath for the correct library (see loadFromResource).
@@ -547,6 +565,8 @@ public class CPUID {
     
     /** 
      * <p>Try loading it from an explictly built jcpuid.dll / libjcpuid.so</p>
+     * The file name must be (e.g. on linux) either libjcpuid.so or libjcpuid-x86-linux.so.
+     * This method does not search for a filename with "_64" in it.
      *
      * @return true if it was loaded successfully, else false
      *
@@ -558,6 +578,13 @@ public class CPUID {
         } catch (UnsatisfiedLinkError ule) {
             // fallthrough, try the OS-specific filename
         }
+
+        // Don't bother trying a 64 bit filename variant.
+
+        // Note this is unlikely to succeed on a standard installation, since when we extract the library
+        // in loadResource() below, we save it as jcpuid.dll / libcupid.so.
+        // However, a distribution may put the file in, e.g., /usr/lib/jni/
+        // with the libjcpuid-x86-linux.so name.
         try {
             System.loadLibrary(getLibraryMiddlePart());
             return true;
@@ -578,14 +605,25 @@ public class CPUID {
      * so we transparently support read-only base dirs.
      * </p>
      *
+     * This tries the 64 bit version first if we think we may be 64 bit.
+     * Then it tries the 32 bit version.
+     *
      * @return true if it was loaded successfully, else false
      *
      */
     private static final boolean loadFromResource() {
-        String resourceName = getResourceName();
-        if (resourceName == null) return false;
-        URL resource = CPUID.class.getClassLoader().getResource(resourceName);
+        URL resource = null;
+        // try 64 bit first, if getResourceName64() returns non-null
+        String resourceName = getResourceName64();
+        if (resourceName != null)
+            resource = CPUID.class.getClassLoader().getResource(resourceName);
         
+        if (resource == null) {
+            // now try 32 bit
+            resourceName = getResourceName();
+            resource = CPUID.class.getClassLoader().getResource(resourceName);
+        }
+
         if (resource == null) {
             if (_doLog)
                 System.err.println("WARNING: Resource name [" + resourceName + "] was not found");
@@ -599,7 +637,6 @@ public class CPUID {
             InputStream libStream = resource.openStream();
             outFile = new File(I2PAppContext.getGlobalContext().getTempDir(), filename);
             fos = new FileOutputStream(outFile);
-            // wtf this was 4096*1024 which is really excessive for a roughly 4KB file
             byte buf[] = new byte[4096];
             while (true) {
                 int read = libStream.read(buf);
@@ -633,14 +670,24 @@ public class CPUID {
         return true;
     }
     
+    /** @return non-null */
     private static final String getResourceName()
     {
         return getLibraryPrefix()+getLibraryMiddlePart()+"."+getLibrarySuffix();
     }
     
+    /**
+     * @return null if not on a 64 bit platform
+     * @since 0.8.7
+     */
+    private static final String getResourceName64() {
+        if (!is64)
+            return null;
+        return getLibraryPrefix() + get64LibraryMiddlePart() + "." + getLibrarySuffix();
+    }
+    
     private static final String getLibraryPrefix()
     {
-        boolean isWindows =System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
         if(isWindows)
             return "";
         else
@@ -648,21 +695,27 @@ public class CPUID {
     }
     
     private static final String getLibraryMiddlePart(){
-        boolean isWindows =(System.getProperty("os.name").toLowerCase().indexOf("windows") != -1);
-        boolean isLinux =(System.getProperty("os.name").toLowerCase().indexOf("linux") != -1);
-        boolean isFreebsd =(System.getProperty("os.name").toLowerCase().indexOf("freebsd") != -1);
         if(isWindows)
              return "jcpuid-x86-windows"; // The convention on Windows
-        if(isLinux)
-            return "jcpuid-x86-linux"; // The convention on linux...
         if(isFreebsd)
             return "jcpuid-x86-freebsd"; // The convention on freebsd...
-        throw new RuntimeException("Dont know jcpuid library name for os type '"+System.getProperty("os.name")+"'");
+        //throw new RuntimeException("Dont know jcpuid library name for os type '"+System.getProperty("os.name")+"'");
+        // use linux as the default, don't throw exception
+        return "jcpuid-x86-linux";
+    }
+    
+    /** @since 0.8.7 */
+    private static final String get64LibraryMiddlePart() {
+        if(isWindows)
+             return "jcpuid-x86_64-windows";
+        if(isFreebsd)
+            return "jcpuid-x86_64-freebsd";
+        // use linux as the default, don't throw exception
+        return "jcpuid-x86_64-linux";
     }
     
     private static final String getLibrarySuffix()
     {
-        boolean isWindows =System.getProperty("os.name").toLowerCase().indexOf("windows") != -1;
         if(isWindows)
             return "dll";
         else