{"id":329,"date":"2015-11-10T10:17:44","date_gmt":"2015-11-10T15:17:44","guid":{"rendered":"https:\/\/blogs.mathworks.com\/graphics\/?p=329"},"modified":"2015-12-02T10:52:59","modified_gmt":"2015-12-02T15:52:59","slug":"memory-consumption","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/graphics\/2015\/11\/10\/memory-consumption\/","title":{"rendered":"Memory Consumption"},"content":{"rendered":"<div class=\"content\">\r\n\r\n<p>Today we're going to look at how MATLAB Graphics uses memory.<\/p>\r\n\r\n<p>First we need a way to tell how much memory MATLAB is using. Because I'm using a Windows system, I can use the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/memory.html\">memory function<\/a>. This isn't the most accurate way to measure memory consumption, but it is easy to use, and it is accurate enough when we're working with large arrays.<\/p>\r\n<pre class=\"codeinput\">rng <span class=\"string\">default<\/span>\r\nminit = memory;\r\nmega = 1024^2;\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,minit.MemUsedMATLAB\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">ans =\r\n\r\n1218.53 MB\r\n\r\n<\/pre>\r\n<p>Now we need a large array. I'm going to create an array with 150 million values, and I'll use the uint8 data type to keep things relatively compact. I'm using some fairly random looking data to make sure that we don't get confused by some optimizations which can kick in for certain types of simple curves.<\/p>\r\n<pre class=\"codeinput\">npts = 150000000;\r\nevents = sort(randi(npts,[500 2]),2);\r\n[~,ix] = sort(abs(events(:,2)-events(:,1)),<span class=\"string\">'descend'<\/span>);\r\nevents = events(ix,:);\r\nd = zeros([1 npts],<span class=\"string\">'uint8'<\/span>);\r\n<span class=\"keyword\">for<\/span> i=1:size(events,1)\r\n    d(events(i,1):events(i,2)) = randi(255,1);\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre>\r\n<p>We can see that this array consumes 150 million bytes, and MATLAB's memory grew by a little more than that.<\/p>\r\n<pre class=\"codeinput\">whos <span class=\"string\">d<\/span>\r\nmarray = memory;\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,(marray.MemUsedMATLAB - minit.MemUsedMATLAB)\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">  Name      Size                       Bytes  Class    Attributes\r\n\r\n  d         1x150000000            150000000  uint8              \r\n\r\n\r\nans =\r\n\r\n152.117 MB\r\n\r\n<\/pre>\r\n<p>Now we'll create a plot from this array. First we'll create a figure and axes.<\/p>\r\n<pre class=\"codeinput\">axes\r\ndrawnow\r\nmaxes = memory;\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,(maxes.MemUsedMATLAB - marray.MemUsedMATLAB)\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">ans =\r\n\r\n26.4648 MB\r\n\r\n<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/memory_consumption_01.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\n<p>That used a little more than 25 megabytes. That's because this is the first time we've used MATLAB Graphics in this session of MATLAB. Because of that, it had to load the graphics libraries, and get OpenGL started. Subsequent plots won't take this hit.<\/p>\r\n\r\n<p>Now we'll call plot.<\/p>\r\n<pre class=\"codeinput\">plot(d)\r\nylim([0 255])\r\ndrawnow\r\n<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/memory_consumption_02.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\n<p>If we check on memory consumption, we'll see that MATLAB is now using another 20 megabytes or so.<\/p>\r\n<pre class=\"codeinput\">mplot = memory;\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,(mplot.MemUsedMATLAB - maxes.MemUsedMATLAB)\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">ans =\r\n\r\n23.4492 MB\r\n\r\n<\/pre>\r\n<p>What do you think will happen if we change one of the values in that array? Let's try it and find out.<\/p>\r\n<pre class=\"codeinput\">d(1000) = 255 - d(1000);\r\nmcow = memory;\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,(mcow.MemUsedMATLAB - mplot.MemUsedMATLAB)\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">ans =\r\n\r\n143.109 MB\r\n\r\n<\/pre>\r\n<p>The amount of memory we're using went way up. That's because MATLAB arrays use something called \"copy on write\". When we first created the plot, the YData property of the line object was using exactly the same memory as the variable d. But when I modified d, the two arrays became \"unshared\". This means that d and the YData are each using 150 million bytes instead of sharing the same 150 million bytes.<\/p>\r\n\r\n<p>But if we set the YData array to be equal to d ...<\/p>\r\n<pre class=\"codeinput\">h = findobj(gca,<span class=\"string\">'Type'<\/span>,<span class=\"string\">'line'<\/span>);\r\nh.YData = d;\r\ndrawnow\r\nmredraw = memory;\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,(mredraw.MemUsedMATLAB - mcow.MemUsedMATLAB)\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">ans =\r\n\r\n-141.316 MB\r\n\r\n<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/memory_consumption_03.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\n<p>... then we get that memory back.<\/p>\r\n\r\n<p>In many cases, a better way to do this is to get rid of the variable in the workspace and modify the YData property of the line directly.<\/p>\r\n<pre class=\"codeinput\">clear <span class=\"string\">d<\/span>\r\nh.YData(1000) = 255 - h.YData(1000);\r\ndrawnow\r\nmydata = memory;\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,(mydata.MemUsedMATLAB - mredraw.MemUsedMATLAB)\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">ans =\r\n\r\n2.75781 MB\r\n\r\n<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/memory_consumption_04.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\n<p>Keeping track of whether your arrays are sharing memory or not is often key to getting the best memory performance out of MATLAB graphics.<\/p>\r\n\r\n<p>Here's another thing to look out for. In our example, we only supplied YData. In this case, the XData starts at 1 and increments by 1 for each data point. Because this is a very common case, the line object doesn't actually allocate any memory for the XData. But if we ask for the value of the XData property, it does allocate it. This means that something as simple as the following can be quite expensive.<\/p>\r\n<pre class=\"codeinput\">disp(size(h.XData))\r\nxdata = memory;\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,(xdata.MemUsedMATLAB - mydata.MemUsedMATLAB)\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">           1   150000000\r\n\r\n\r\nans =\r\n\r\n1145.31 MB\r\n\r\n<\/pre>\r\n<p>What happened there is that it needed an array to pass to the size function, so it created one. And since the default datatype is double, it created a really big one! It's eight times the size of the array we originally passed in. That's pretty wasteful for an array which looks like this:<\/p>\r\n<pre>1 2 3 4 5 6 7 8 9 ...<\/pre>\r\n<p>So far we've been talking about the memory that is used by MATLAB's arrays. But there's actually a different type of memory that was getting used when we create the plot. MATLAB loads a copy of the geometry into the memory of the graphics card. It's important that the graphics card has a copy that is local, and is organized just right, so that it can redraw it as quickly as possible. A lot of the 20 megabytes that were used by the plot command were this type of memory.<\/p>\r\n\r\n<p>But notice that this is quite a bit smaller than the original array. MATLAB Graphics generates a low-res version of the shape and sends that to the graphics card. But that low-res version has to contain enough data to capture all of those details in the shape. Getting this right is pretty tricky.<\/p>\r\n\r\n<p>We call this step \"level-of-detail\" or \"LOD\". Level-of-detail algorithms are an important field of computer graphics. Unfortunately there isn't one simple algorithm which works for all types of geometry and in all types of situations. MATLAB Graphics currently has LOD algorithms for plot, line and image. We're working on improving those, and on adding more. But if you're working with one of the other types of graphics objects, then you won't be getting this LOD reduction, and MATLAB will be sending all of the geometry to the graphics card.<\/p>\r\n\r\n<p>There actually is one other LOD algorithm in MATLAB. It's for the Patch object, and it is called <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/reducepatch.html\">reducepatch<\/a>. At this point, we don't think that reducepatch is fast enough or reliable enough to build into the patch command so that it runs automatically. But you might want to use it when you are working with a really complex patch object.<\/p>\r\n\r\n<p>If the data you're plotting is small, then we skip the LOD step and simply put all of the geometry into the memory of the graphics card.<\/p>\r\n\r\n<p>Now lets save the plot to a FIG file.<\/p>\r\n<pre class=\"codeinput\">fig = gcf;\r\nfname = <span class=\"string\">'c:\\temp\\default.fig'<\/span>;\r\ntic\r\nsavefig(fig,fname)\r\ntoc\r\n<\/pre>\r\n<pre class=\"codeoutput\">Elapsed time is 102.143896 seconds.\r\n<\/pre>\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/graphics\/2015\/memory_consumption_05.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\n<p>That took more than a minute and a half, and if we look at the file, we'll see that it's more than 380 megabytes.<\/p>\r\n<pre class=\"codeinput\">s = dir(fname);\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,s.bytes\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">ans =\r\n\r\n386.894 MB\r\n\r\n<\/pre>\r\n<p>That's pretty big! There are a couple of reasons for this, but the biggest one is that it actually saved two copies. The reason for this is that in R2014b, the internals of MATLAB Graphics changed enormously. So if we want to create a FIG file which can be read by any version of MATLAB, we need to save a copy in the old format as well as a copy in the new format.<\/p>\r\n\r\n<p>We can tell savefig not to do this by adding the compact flag.<\/p>\r\n\r\n<p>If we do this, the save only takes about 1\/2 as long.<\/p>\r\n<pre class=\"codeinput\">tic\r\nfname = <span class=\"string\">'c:\\temp\\compact.fig'<\/span>;\r\nsavefig(fig,fname,<span class=\"string\">'compact'<\/span>)\r\ntoc\r\n<\/pre>\r\n<pre class=\"codeoutput\">Elapsed time is 55.061655 seconds.\r\n<\/pre>\r\n<p>And we can see that the resulting FIG file is less than 1\/2 as large.<\/p>\r\n<pre class=\"codeinput\">s = dir(fname);\r\nsprintf(<span class=\"string\">'%g MB'<\/span>,s.bytes\/mega)\r\n<\/pre>\r\n<pre class=\"codeoutput\">ans =\r\n\r\n185.968 MB\r\n\r\n<\/pre>\r\n<p>That can be useful if you don't have any copies of MATLAB which are older than R2014b. The compact option is fine for saving and loading FIG files in newer versions, and it's much less expensive.<\/p>\r\n\r\n<p>If you are using a version of MATLAB which is older than R2014b, you should know that there are a number of important differences in how MATLAB Graphics managed memory in older versions.<\/p>\r\n<div>\r\n<ol>\r\n\t<li>In older versions, MATLAB Graphics was loaded at MATLAB startup. This means that there isn't extra memory consumed on the first plot, but it means that MATLAB is using that memory even if you never do any graphics.<\/li>\r\n\t<li>In older versions, MATLAB Graphics didn't support datatypes such as uint8 very well. As a result, it often copied the data into a double array, which consumed a LARGE amount of memory. This also meant that the \"copy on write\" memory sharing I described didn't occur.<\/li>\r\n\t<li>In older versions, MATLAB Graphics was less aggressive about moving geometry into the memory of the graphics card. That was sometimes good in cases like this, where we're only drawing the data once. But it was a bottleneck in cases where we are repeatedly drawing the same data.<\/li>\r\n\t<li>The compact option on savefig was introduced in R2014b because earlier versions only saved the one copy.<\/li>\r\n<\/ol>\r\n<\/div>\r\n<p>It's also important to know that the level-of-detail algorithms in MATLAB Graphics are continuing to evolve and get better. So the amount of memory consumed in that step should continue to get smaller in future releases.<\/p>\r\n\r\n<p>I hope that this has given you some insight into how MATLAB Graphics uses memory. Hopefully it will give you some ideas about how to free up more memory for your computations.<\/p>\r\n\r\n<script>\r\nfunction grabCode_32dfaf41ec164f83be77ae80c8f3275c() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='32dfaf41ec164f83be77ae80c8f3275c ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 32dfaf41ec164f83be77ae80c8f3275c';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2015 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('\r\n\r\n<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\r\n\r\n\r\n\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }\r\n<\/script>\r\n<p style=\"text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;\">\r\n<a><span style=\"font-size: x-small; font-style: italic;\">Get\r\nthe MATLAB code<noscript>(requires JavaScript)<\/noscript><\/span><\/a>\r\n\r\nPublished with MATLAB\u00ae R2015b<\/p>\r\n\r\n<\/div>\r\n<!--\r\n32dfaf41ec164f83be77ae80c8f3275c ##### SOURCE BEGIN #####\r\n%%\r\n% Today we're going to look at how MATLAB Graphics uses memory.\r\n%\r\n% First we need a way to tell how much memory MATLAB is using. Because I'm\r\n% using a Windows system, I can use the <https:\/\/www.mathworks.com\/help\/matlab\/ref\/memory.html memory function>.\r\n% This isn't the most accurate way to measure memory consumption, but it is\r\n% easy to use, and it is accurate enough when we're working with large\r\n% arrays.\r\n%\r\nrng default\r\nminit = memory;\r\nmega = 1024^2;\r\nsprintf('%g MB',minit.MemUsedMATLAB\/mega)\r\n\r\n%%\r\n% Now we need a large array. I'm going to create an array with 150 million\r\n% values, and I'll use the uint8 data type to keep things relatively compact.\r\n% I'm using some fairly random looking data to make sure that we don't get\r\n% confused by some optimizations which can kick in for certain types of\r\n% simple curves.\r\n%\r\nnpts = 150000000;\r\nevents = sort(randi(npts,[500 2]),2);\r\n[~,ix] = sort(abs(events(:,2)-events(:,1)),'descend');\r\nevents = events(ix,:);\r\nd = zeros([1 npts],'uint8');\r\nfor i=1:size(events,1)\r\nd(events(i,1):events(i,2)) = randi(255,1);\r\nend\r\n\r\n%%\r\n% We can see that this array consumes 150 million bytes, and MATLAB's\r\n% memory grew by a little more than that.\r\n%\r\nwhos d\r\nmarray = memory;\r\nsprintf('%g MB',(marray.MemUsedMATLAB - minit.MemUsedMATLAB)\/mega)\r\n\r\n%%\r\n% Now we'll create a plot from this array. First we'll create a figure and\r\n% axes.\r\n%\r\naxes\r\ndrawnow\r\nmaxes = memory;\r\nsprintf('%g MB',(maxes.MemUsedMATLAB - marray.MemUsedMATLAB)\/mega)\r\n\r\n%%\r\n% That used a little more than 25 megabytes. That's because this is the first time we've\r\n% used MATLAB Graphics in this session of MATLAB. Because of that, it had\r\n% to load the graphics libraries, and get OpenGL started. Subsequent plots\r\n% won't take this hit.\r\n%\r\n% Now we'll call plot.\r\n%\r\nplot(d)\r\nylim([0 255])\r\ndrawnow\r\n\r\n%%\r\n% If we check on memory consumption, we'll see that MATLAB is now using\r\n% another 20 megabytes or so.\r\n%\r\nmplot = memory;\r\nsprintf('%g MB',(mplot.MemUsedMATLAB - maxes.MemUsedMATLAB)\/mega)\r\n\r\n%%\r\n% What do you think will happen if we change one of the values in that\r\n% array? Let's try it and find out.\r\n%\r\nd(1000) = 255 - d(1000);\r\nmcow = memory;\r\nsprintf('%g MB',(mcow.MemUsedMATLAB - mplot.MemUsedMATLAB)\/mega)\r\n\r\n%%\r\n% The amount of memory we're using went way up. That's because MATLAB\r\n% arrays use something called \"copy on write\". When we first created the\r\n% plot, the YData property of the line object was using exactly the same\r\n% memory as the variable d. But when I modified d, the two arrays became\r\n% \"unshared\". This means that d and the YData are each using 150 million\r\n% bytes instead of sharing the same 150 million bytes.\r\n%\r\n\r\n%%\r\n% But if we set the YData array to be equal to d ...\r\n%\r\nh = findobj(gca,'Type','line');\r\nh.YData = d;\r\ndrawnow\r\nmredraw = memory;\r\nsprintf('%g MB',(mredraw.MemUsedMATLAB - mcow.MemUsedMATLAB)\/mega)\r\n\r\n%%\r\n% ... then we get that memory back.\r\n%\r\n% In many cases, a better way to do this is to get rid of the variable in\r\n% the workspace and modify the YData property of the line directly.\r\n%\r\nclear d\r\nh.YData(1000) = 255 - h.YData(1000);\r\ndrawnow\r\nmydata = memory;\r\nsprintf('%g MB',(mydata.MemUsedMATLAB - mredraw.MemUsedMATLAB)\/mega)\r\n\r\n%%\r\n% Keeping track of whether your arrays\r\n% are sharing memory or not is often key to getting the best memory\r\n% performance out of MATLAB graphics.\r\n%\r\n\r\n%%\r\n% Here's another thing to look out for. In our example, we only supplied\r\n% YData. In this case, the XData starts at 1 and increments by 1 for each\r\n% data point. Because this is a very common case, the line object doesn't\r\n% actually allocate any memory for the XData. But if we ask for the value\r\n% of the XData property, it does allocate it. This means that something as\r\n% simple as the following can be quite expensive.\r\n%\r\ndisp(size(h.XData))\r\nxdata = memory;\r\nsprintf('%g MB',(xdata.MemUsedMATLAB - mydata.MemUsedMATLAB)\/mega)\r\n\r\n%%\r\n% What happened there is that it needed an array to pass to the size\r\n% function, so it created one. And since the default datatype is double, it\r\n% created a really big one! It's eight times the size of the array we\r\n% originally passed in. That's pretty wasteful for an array which looks\r\n% like this:\r\n%\r\n%  1 2 3 4 5 6 7 8 9 ...\r\n%\r\n\r\n%%\r\n% So far we've been talking about the memory that is used by MATLAB's\r\n% arrays. But there's actually a different type of memory that was getting\r\n% used when we create the plot. MATLAB loads a copy of the geometry\r\n% into the memory of the graphics card. It's important that the graphics\r\n% card has a copy that is local, and is organized just right, so that it\r\n% can redraw it as quickly as possible. A lot of the 20 megabytes that were\r\n% used by the plot command were this type of memory.\r\n%\r\n% But notice that this is quite a bit smaller than the original array. MATLAB Graphics generates a low-res\r\n% version of the shape and sends that to the graphics card. But that\r\n% low-res version has to contain enough data to capture all of those\r\n% details in the shape. Getting this right is pretty tricky.\r\n%\r\n% We call this step \"level-of-detail\" or \"LOD\". Level-of-detail algorithms are an\r\n% important field of computer graphics. Unfortunately there isn't one\r\n% simple algorithm which works for all types of geometry and in all types\r\n% of situations. MATLAB Graphics currently has LOD algorithms for plot,\r\n% line and image. We're working on improving those, and on adding more. But\r\n% if you're working with one of the other types of graphics objects, then\r\n% you won't be getting this LOD reduction, and MATLAB will be sending all\r\n% of the geometry to the graphics card.\r\n%\r\n% There actually is one other LOD algorithm in MATLAB. It's for the Patch\r\n% object, and it is called <https:\/\/www.mathworks.com\/help\/matlab\/ref\/reducepatch.html reducepatch>.\r\n% At this point, we don't think that reducepatch is fast\r\n% enough or reliable enough to build into the patch command so that it runs automatically.\r\n% But you might want to use it when you are working with a really complex patch object.\r\n%\r\n% If the data you're plotting is small, then we skip the LOD step and\r\n% simply put all of the geometry into the memory of the graphics card.\r\n%\r\n\r\n%%\r\n% Now lets save the plot to a FIG file.\r\n%\r\nfig = gcf;\r\nfname = 'c:\\temp\\default.fig';\r\ntic\r\nsavefig(fig,fname)\r\ntoc\r\n\r\n%%\r\n% That took more than a minute and a half, and if we look at the file, we'll see that\r\n% it's more than 380 megabytes.\r\n%\r\ns = dir(fname);\r\nsprintf('%g MB',s.bytes\/mega)\r\n\r\n%%\r\n% That's pretty big! There are a couple of reasons for this, but the\r\n% biggest one is that it actually saved two copies. The reason for this is\r\n% that in R2014b, the internals of MATLAB Graphics changed enormously. So\r\n% if we want to create a FIG file which can be read by any version of\r\n% MATLAB, we need to save a copy in the old format as well as a copy in the\r\n% new format.\r\n\r\n%%\r\n% We can tell savefig not to do this by adding the compact flag.\r\n%\r\n% If we do this, the save only takes about 1\/2 as long.\r\ntic\r\nfname = 'c:\\temp\\compact.fig';\r\nsavefig(fig,fname,'compact')\r\ntoc\r\n\r\n%%\r\n% And we can see that the resulting FIG file is less than 1\/2 as large.\r\n%\r\ns = dir(fname);\r\nsprintf('%g MB',s.bytes\/mega)\r\n\r\n%%\r\n% That can be useful if you don't have any copies of MATLAB which are older\r\n% than R2014b. The compact option is fine for saving and loading FIG files\r\n% in newer versions, and it's much less expensive.\r\n%\r\n% If you are using a version of MATLAB which is older than R2014b, you\r\n% should know that there are a number of important differences in how\r\n% MATLAB Graphics managed memory in older versions.\r\n%\r\n% # In older versions, MATLAB Graphics was loaded at MATLAB startup. This means that there isn't extra memory consumed on the first plot, but it means that MATLAB is using that memory even if you never do any graphics.\r\n% # In older versions, MATLAB Graphics didn't support datatypes such as\r\n% uint8 very well. As a result, it often copied the data into a double\r\n% array, which consumed a LARGE amount of memory. This also meant that the \"copy on write\" memory sharing I described didn't occur.\r\n% # In older versions, MATLAB Graphics was less aggressive about moving geometry into the memory of the graphics card. That was sometimes good in cases like this, where we're only drawing the data once. But it was a bottleneck in cases where we are repeatedly drawing the same data.\r\n% # The compact option on savefig was introduced in R2014b because earlier versions only saved the one copy.\r\n%\r\n% It's also important to know that the level-of-detail algorithms in MATLAB\r\n% Graphics are continuing to evolve and get better. So the amount of memory\r\n% consumed in that step should continue to get smaller in future releases.\r\n%\r\n% I hope that this has given you some insight into how MATLAB Graphics uses\r\n% memory. Hopefully it will give you some ideas about how to free up more\r\n% memory for your computations.\r\n%\r\n##### SOURCE END ##### 32dfaf41ec164f83be77ae80c8f3275c\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/graphics\/files\/feature_image\/memory_consumption_thumbnail.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>\r\n\r\nToday we're going to look at how MATLAB Graphics uses memory.\r\n\r\nFirst we need a way to tell how much memory MATLAB is using. Because I'm using a Windows system, I can use the memory function.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/graphics\/2015\/11\/10\/memory-consumption\/\">read more >><\/a><\/p>","protected":false},"author":89,"featured_media":332,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[8],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/329"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/users\/89"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/comments?post=329"}],"version-history":[{"count":11,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/329\/revisions"}],"predecessor-version":[{"id":347,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/posts\/329\/revisions\/347"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media\/332"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/media?parent=329"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/categories?post=329"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/graphics\/wp-json\/wp\/v2\/tags?post=329"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}