Index: trunk/src/org/openstreetmap/josm/data/cache/JCSCacheManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/JCSCacheManager.java	(revision 8658)
+++ trunk/src/org/openstreetmap/josm/data/cache/JCSCacheManager.java	(revision 8659)
@@ -39,5 +39,5 @@
 
     private static volatile CompositeCacheManager cacheManager = null;
-    private static long maxObjectTTL        = Long.MAX_VALUE;
+    private static long maxObjectTTL        = -1;
     private static final String PREFERENCE_PREFIX = "jcs.cache";
     private static final AuxiliaryCacheFactory diskCacheFactory = new IndexedDiskCacheFactory();
Index: trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java	(revision 8658)
+++ trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java	(revision 8659)
@@ -43,4 +43,5 @@
     private int[] tileXMax;
     private int[] tileYMax;
+    private double[] degreesPerTile;
 
     private static final Pattern PATTERN_HEADER  = Pattern.compile("\\{header\\(([^,]+),([^}]+)\\)\\}");
@@ -95,9 +96,17 @@
         tileXMax = new int[getMaxZoom() + 1];
         tileYMax = new int[getMaxZoom() + 1];
+        degreesPerTile = new double[getMaxZoom() +1];
         for (int zoom = getMinZoom(); zoom <= getMaxZoom(); zoom++) {
             TileXY maxTileIndex = latLonToTileXY(bottomRight.toCoordinate(), zoom);
             tileXMax[zoom] = maxTileIndex.getXIndex();
             tileYMax[zoom] = maxTileIndex.getYIndex();
-        }
+            int tilesPerZoom = (int) Math.pow(2d, zoom - 1);
+            degreesPerTile[zoom] = Math.max(
+                    Math.abs(max.getY() - min.getY()) / tilesPerZoom,
+                    Math.abs(max.getX() - min.getX()) / tilesPerZoom
+                    );
+
+        }
+
     }
 
@@ -382,13 +391,5 @@
 
     private double getDegreesPerTile(int zoom) {
-        Projection proj = Main.getProjection();
-        EastNorth min = proj.latlon2eastNorth(worldBounds.getMin());
-        EastNorth max = proj.latlon2eastNorth(worldBounds.getMax());
-
-        int tilesPerZoom = (int) Math.pow(2d, zoom - 1);
-        return Math.max(
-                Math.abs(max.getY() - min.getY()) / tilesPerZoom,
-                Math.abs(max.getX() - min.getX()) / tilesPerZoom
-                );
+        return degreesPerTile[zoom];
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/AbstractCachedTileSourceLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/AbstractCachedTileSourceLayer.java	(revision 8658)
+++ trunk/src/org/openstreetmap/josm/gui/layer/AbstractCachedTileSourceLayer.java	(revision 8659)
@@ -36,9 +36,4 @@
      */
     public static final IntegerProperty MAX_DISK_CACHE_SIZE = new IntegerProperty(PREFERENCE_PREFIX + "max_disk_size", 512);
-
-    /**
-     * use fairly small memory cache, as cached objects are quite big, as they contain BufferedImages
-     */
-    public static final IntegerProperty MEMORY_CACHE_SIZE = new IntegerProperty(PREFERENCE_PREFIX + "cache.max_objects_ram", 200);
 
     private ICacheAccess<String, BufferedImageCacheEntry> cache;
Index: trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 8658)
+++ trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 8659)
@@ -134,5 +134,17 @@
     public boolean showErrors;
 
-    protected TileCache tileCache;
+    /**
+     * use fairly small memory cache, as cached objects are quite big, as they contain BufferedImages
+     */
+    public static final IntegerProperty MEMORY_CACHE_SIZE = new IntegerProperty(PREFERENCE_PREFIX + "cache.max_objects_ram", 200);
+
+    /*
+     *  use MemoryTileCache instead of tileLoader JCS cache, as tileLoader caches only content (byte[] of image)
+     *  and MemoryTileCache caches whole Tile. This gives huge performance improvement when a lot of tiles are visible
+     *  in MapView (for example - when limiting min zoom in imagery)
+     *
+     *  Use static instance so memory is shared between layers to prevent out of memory exceptions, when user is working with many layers
+     */
+    protected static TileCache tileCache = new MemoryTileCache(MEMORY_CACHE_SIZE.get());
     protected AbstractTMSTileSource tileSource;
     protected TileLoader tileLoader;
@@ -174,10 +186,4 @@
 
         tileLoader = getTileLoaderFactory().makeTileLoader(this, headers);
-        /*
-         *  use MemoryTileCache instead of tileLoader JCS cache, as tileLoader caches only content (byte[] of image)
-         *  and MemoryTileCache caches whole Tile. This gives huge performance improvement when a lot of tiles are visible
-         *  in MapView (for example - when limiting min zoom in imagery)
-         */
-        tileCache = new MemoryTileCache(AbstractCachedTileSourceLayer.MEMORY_CACHE_SIZE.get());
 
         try {
