 <p>This is definitely a nasty memory leak. I've <a href="https://code.google.com/p/android/issues/detail?id=60071" rel="nofollow">opened an issue</a> for it since no one else seems to have reported it.</p> <p>Thanks for the "ugly workaround" emmby, that was helpful. A safer approach, although potentially with a performance impact, is to disable URLConnection caching altogether. Since the URLConnection.defaultUseCaches flag is static and, as you might guess, is the default for each instance's useCaches flag, you can just set this to false and no more instances will cache their connections. This will affect all implementations of URLConnection, so it may have farther-ranging effects than desired, but I think it's a reasonable trade-off.</p> <p>You can just create a simple class like this and instantiate it very early in your app's onCreate():</p> <pre><code>public class URLConnectionNoCache extends URLConnection { protected URLConnectionNoCache(URL url) { super(url); setDefaultUseCaches(false); } public void connect() throws IOException { } } </code></pre> <p>The interesting thing is that since this occurs after your app is loaded and run, the system libs should already be cached, and this will only prevent further caching, so this probably gives the best possible trade-off: not caching your apk while allowing the performance benefits of caching the system jars.</p> <p>Before doing this I did modify emmby's solution a bit to make it a standalone class that creates a background thread to periodically clear the cache. And I restricted it to just clear the app's apk, though that can be relaxed if desired. The thing to worry about here is that you're modifying the objects while they may be in use, which is generally not a good thing. If you do want to go this route you just need to call the start() method with a context, e.g. in your app's onCreate().</p> <pre><code>package com.example; import java.lang.reflect.Field; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.jar.JarFile; import java.util.regex.Pattern; import android.content.Context; // hack to remove memory leak in JarURLConnectionImpl // from http://stackoverflow.com/questions/14610350/android-memory-leak-in-apache-harmonys-jarurlconnectionimpl public class JarURLMonitor { private static JarURLMonitor instance; private Pattern pat; private Field jarCacheField; public volatile boolean stop; private static final long CHECK_INTERVAL = 60 * 1000; public static synchronized void start(Context context) { if (instance == null) { instance = new JarURLMonitor(context); } } public static synchronized void stop() { if (instance != null) { instance.stop = true; } } private JarURLMonitor(Context context) { // get jar cache field try { final Class&lt;?&gt; cls = Class.forName("libcore.net.url.JarURLConnectionImpl"); jarCacheField = cls.getDeclaredField("jarCache"); jarCacheField.setAccessible(true); } catch (Exception e) { // log } if (jarCacheField != null) { // create pattern that matches our package: e.g. /data/app/&lt;pkgname&gt;-1.apk pat = Pattern.compile("^.*/" + context.getPackageName() + "-.*\\.apk$"); // start background thread to check it new Thread("JarURLMonitor") { @Override public void run() { try { while (!stop) { checkJarCache(); Thread.sleep(CHECK_INTERVAL); } } catch (Exception e) { // log } } }.start(); } } private void checkJarCache() throws Exception { @SuppressWarnings("unchecked") final HashMap&lt;URL, JarFile&gt; jarCache = (HashMap&lt;URL, JarFile&gt;)jarCacheField.get(null); final Iterator&lt;Map.Entry&lt;URL, JarFile&gt;&gt; iterator = jarCache.entrySet().iterator(); while (iterator.hasNext()) { final Map.Entry&lt;URL, JarFile&gt; entry = iterator.next(); final JarFile jarFile = entry.getValue(); final String file = jarFile.getName(); if (pat.matcher(file).matches()) { try { jarFile.close(); iterator.remove(); } catch (Exception e) { // log } } } } } </code></pre>