diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp
index f1920490d..0b8f933a2 100644
--- a/apps/openmw/mwrender/terrain.cpp
+++ b/apps/openmw/mwrender/terrain.cpp
@@ -98,7 +98,10 @@ namespace MWRender
         ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
         if ( land != NULL )
         {
-            land->loadData();
+            if (!land->dataLoaded)
+            {
+                land->loadData();
+            }
         }
 
         //split the cell terrain into four segments
@@ -133,7 +136,7 @@ namespace MWRender
                         const size_t xOffset = x * (mLandSize-1);
 
                         memcpy(&terrainData.inputFloat[terrainCopyY*mLandSize],
-                               &land->landData.heights[yOffset + xOffset],
+                               &land->landData->heights[yOffset + xOffset],
                                mLandSize*sizeof(float));
                     }
                 }
@@ -160,7 +163,7 @@ namespace MWRender
                                          numTextures,
                                          indexes);
 
-                    if ( land && land->landData.usingColours )
+                    if ( land && land->landData->usingColours )
                     {
                         // disable or enable global colour map (depends on available vertex colours)
                         mActiveProfile->setGlobalColourMapEnabled(true);
@@ -420,12 +423,18 @@ namespace MWRender
         ESM::Land* land = mEnvironment.mWorld->getStore().lands.search(cellX, cellY);
         if ( land != NULL )
         {
-            land->loadData();
+            if (!land->dataLoaded)
+            {
+                land->loadData();
+            }
 
-            return land->landData.textures[y * ESM::Land::LAND_TEXTURE_SIZE + x];
+            return land->landData
+                       ->textures[y * ESM::Land::LAND_TEXTURE_SIZE + x];
+        }
+        else
+        {
+            return 0;
         }
-
-        return 0;
     }
 
     //----------------------------------------------------------------------------------------------
@@ -464,7 +473,7 @@ namespace MWRender
 
         if ( land != NULL )
         {
-            const char* const colours = land->landData.colours;
+            const char* const colours = land->landData->colours;
             for ( int y = 0; y < size; y++ )
             {
                 for ( int x = 0; x < size; x++ )
diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp
index c6dc3c6f2..96afdf831 100644
--- a/components/esm/loadland.cpp
+++ b/components/esm/loadland.cpp
@@ -10,10 +10,16 @@ Land::Land()
     , mEsm(NULL)
     , hasData(false)
     , dataLoaded(false)
+    , landData(NULL)
 {
-    memset(&landData, 0, sizeof(landData));
 }
 
+Land::~Land()
+{
+    delete landData;
+}
+
+
 void Land::load(ESMReader &esm)
 {
     mEsm = &esm;
@@ -62,6 +68,7 @@ void Land::load(ESMReader &esm)
     hasData = (cnt == 3);
 
     dataLoaded = false;
+    landData = NULL;
 }
 
 void Land::loadData()
@@ -71,6 +78,8 @@ void Land::loadData()
         return;
     }
 
+    landData = new LandData;
+
     if (hasData)
     {
         mEsm->restoreContext(context);
@@ -82,20 +91,19 @@ void Land::loadData()
         }
 
         VHGT rawHeights;
-        memset(&rawHeights, 0, sizeof(rawHeights));
 
         mEsm->getHNExact(&rawHeights, sizeof(VHGT), "VHGT");
         int currentHeightOffset = rawHeights.heightOffset;
         for (int y = 0; y < LAND_SIZE; y++)
         {
             currentHeightOffset += rawHeights.heightData[y * LAND_SIZE];
-            landData.heights[y * LAND_SIZE] = currentHeightOffset * HEIGHT_SCALE;
+            landData->heights[y * LAND_SIZE] = currentHeightOffset * HEIGHT_SCALE;
 
             int tempOffset = currentHeightOffset;
             for (int x = 1; x < LAND_SIZE; x++)
             {
                 tempOffset += rawHeights.heightData[y * LAND_SIZE + x];
-                landData.heights[x + y * LAND_SIZE] = tempOffset * HEIGHT_SCALE;
+                landData->heights[x + y * LAND_SIZE] = tempOffset * HEIGHT_SCALE;
             }
         }
 
@@ -105,10 +113,10 @@ void Land::loadData()
         }
         if (mEsm->isNextSub("VCLR"))
         {
-            landData.usingColours = true;
-            mEsm->getHExact(&landData.colours, 3*LAND_NUM_VERTS);
+            landData->usingColours = true;
+            mEsm->getHExact(&landData->colours, 3*LAND_NUM_VERTS);
         }else{
-            landData.usingColours = false;
+            landData->usingColours = false;
         }
         //TODO fix magic numbers
         uint16_t vtex[512];
@@ -119,19 +127,29 @@ void Land::loadData()
             for ( int x1 = 0; x1 < 4; x1++ )
                 for ( int y2 = 0; y2 < 4; y2++)
                     for ( int x2 = 0; x2 < 4; x2++ )
-                        landData.textures[(y1*4+y2)*16+(x1*4+x2)] = vtex[readPos++];
+                        landData->textures[(y1*4+y2)*16+(x1*4+x2)] = vtex[readPos++];
     }
     else
     {
-        landData.usingColours = false;
-        memset(landData.textures, 0, sizeof(landData.textures));
+        landData->usingColours = false;
+        memset(&landData->textures, 0, 512 * sizeof(uint16_t));
         for (int i = 0; i < LAND_NUM_VERTS; i++)
         {
-            landData.heights[i] = -256.0f * HEIGHT_SCALE;
+            landData->heights[i] = -256.0f * HEIGHT_SCALE;
         }
     }
 
     dataLoaded = true;
 }
 
+void Land::unloadData()
+{
+    if (dataLoaded)
+    {
+        delete landData;
+        landData = NULL;
+        dataLoaded = false;
+    }
+}
+
 }
diff --git a/components/esm/loadland.hpp b/components/esm/loadland.hpp
index 86f37d575..64baecd34 100644
--- a/components/esm/loadland.hpp
+++ b/components/esm/loadland.hpp
@@ -12,6 +12,7 @@ namespace ESM
 struct Land
 {
     Land();
+    ~Land();
 
     int flags; // Only first four bits seem to be used, don't know what
     // they mean.
@@ -66,7 +67,7 @@ struct Land
         char colours[3 * LAND_NUM_VERTS];
     };
 
-    LandData landData;
+    LandData *landData;
 
     void load(ESMReader &esm);
 
@@ -74,6 +75,11 @@ struct Land
      * Actually loads data
      */
     void loadData();
+
+    /**
+     * Frees memory allocated for land data
+     */
+    void unloadData();
 };
 }
 #endif