{"id":36,"date":"2006-05-10T10:29:27","date_gmt":"2006-05-10T15:29:27","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=36"},"modified":"2017-03-28T13:02:51","modified_gmt":"2017-03-28T18:02:51","slug":"memory-management-for-functions-and-variables","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2006\/05\/10\/memory-management-for-functions-and-variables\/","title":{"rendered":"Memory Management for Functions and Variables"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>People have different ideas about what costs a lot, in terms of memory, in MATLAB.  And sometimes people don't know the details.\r\n         Today I am going to talk about when MATLAB makes copies of data, for both calling functions, and for data stored in variables.\r\n         MATLAB makes copies of arrays it passes only when the data referred to changes (this is called copy on write or lazy copying).\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h3>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Passing Arrays to Functions<\/a><\/li>\r\n         <li><a href=\"#3\">Structures and Memory<\/a><\/li>\r\n         <li><a href=\"#4\">Create some rgb image data with 3 planes: red, green, and blue.<\/a><\/li>\r\n         <li><a href=\"#11\">What's Your Mental Model for MATLAB Memory Management?<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Passing Arrays to Functions<a name=\"1\"><\/a><\/h3>\r\n   <p>The question is, when does MATLAB copy memory when passing arrays to functions.  Some users think that because MATLAB behaves\r\n      as if data are passed by value (as opposed to by reference), that MATLAB always makes copies of the inputs when calling a\r\n      function.  This is not necessarily true.  Take a look at this function.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">type <span style=\"color: #A020F0\">fred1<\/span><\/pre><pre style=\"font-style:oblique\">\r\nfunction y = foo(x,a,b) \r\na(1) = a(1) + 12; \r\ny = a * x + b;\r\n<\/pre><p>In <tt>fred1<\/tt>, the first and third inputs, <tt>x<\/tt> and <tt>b<\/tt>, are not altered inside.  MATLAB recognizes this and passes both these variables in without making any extra copies.  This\r\n      can be a big memory savings, for example, if <tt>x<\/tt> is a large dataset.  However, in <tt>fred1<\/tt>, we can see that the second input, <tt>a<\/tt>, gets modified inside.  MATLAB recognizes when this is happening to a variable and makes a copy of it to work with so that\r\n      the original variable in the calling workspace is not modified.\r\n   <\/p>\r\n   <h3>Structures and Memory<a name=\"3\"><\/a><\/h3>\r\n   <p>Each structure member is treated as a separate array in MATLAB. This means that if you modify one member of a structure, the\r\n      other members, which are unchanged, are not copied.  It's time for an illustration here.\r\n   <\/p>\r\n   <h3>Create some rgb image data with 3 planes: red, green, and blue.<a name=\"4\"><\/a><\/h3><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">im1.r = rand(300,300);\r\nim1.g = rand(300,300);\r\nim1.b = rand(300,300);<\/pre><p>Instead, rearrange the same data so that we have an array of structs each element containing an <tt>[r g b]<\/tt>-triplet.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">im2(300,300).rgb = [0 0 0];  <span style=\"color: #228B22\">% preallocate the array<\/span>\r\n<span style=\"color: #0000FF\">for<\/span> r = 1:300\r\n    <span style=\"color: #0000FF\">for<\/span> c = 1:300\r\n        im2(r,c).rgb = [im1.r(r,c) im1.g(r,c) im1.b(r,c)];\r\n    <span style=\"color: #0000FF\">end<\/span>\r\n<span style=\"color: #0000FF\">end<\/span><\/pre><p>Let&#8217;s compare <tt>im1<\/tt> and <tt>im2<\/tt>.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">clear <span style=\"color: #A020F0\">c<\/span> <span style=\"color: #A020F0\">r<\/span>  <span style=\"color: #228B22\">% tidy up the workspace<\/span>\r\nwhos<\/pre><pre style=\"font-style:oblique\">  Name       Size                    Bytes  Class\r\n\r\n  im1        1x1                   2160372  struct array\r\n  im2      300x300                 7560064  struct array\r\n  s          1x1                       392  struct array\r\n  sNew       1x1                       392  struct array\r\n\r\nGrand total is 630043 elements using 9721220 bytes\r\n\r\n<\/pre><p><tt>im1<\/tt> is a scalar structure with members that hold m x n arrays.\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li> <tt>im1.r<\/tt> = imageRedPlane            --- size m x n\r\n         <\/li>\r\n         <li> <tt>im1.g<\/tt> = imageGreenPlane          --- size m x n\r\n         <\/li>\r\n         <li> <tt>im1.b<\/tt> = imageBluePlane           --- size m x n\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p><tt>im1<\/tt> is size 1 x 1; total # of arrays inside <tt>im1<\/tt>: 3\r\n   <\/p>\r\n   <p><tt>im2<\/tt> is an m x n structure array with fields containing 3-element vectors.\r\n   <\/p>\r\n   <div>\r\n      <ul>\r\n         <li><tt>im2(i,j).rgb<\/tt> = imageOneRGBPixel  --- size 1 x 3\r\n         <\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <p><tt>im2<\/tt> is size m x n; total # of arrays inside <tt>im2<\/tt>: m x n\r\n   <\/p>\r\n   <p>Notes: Every MATLAB array allocates a header with information. This makes <tt>im1<\/tt> more memory-efficient than <tt>im2<\/tt> (more generally, scalar structs containing arrays are more memory-efficient than a struct array). When one field in a structure\r\n      is changed, and possibly copied, the other fields are left intact.\r\n   <\/p><pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">s.A = rand(3);\r\ns.B = magic(3);\r\nsNew = s;\r\nsNew.A(3) = 14;<\/pre><p>Since <tt>s<\/tt> and <tt>sNew<\/tt> have unaltered copies of <tt>B<\/tt>, the <tt>B<\/tt> fields share memory, but the <tt>A<\/tt> fields do not. See the documentation section titled <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_prog\/strategies-for-efficient-use-of-memory.html\">Using Memory Efficiently<\/a> for more information.\r\n   <\/p>\r\n   <h3>What's Your Mental Model for MATLAB Memory Management?<a name=\"11\"><\/a><\/h3>\r\n   <p>Say that three times fast!<\/p>\r\n   <p>Does the description here and\/or in the documentation change your model?<\/p>\r\n   <p>Let me know.<\/p>\r\n   <p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br>\r\n      Published with MATLAB&reg; 7.2<br><\/p>\r\n<\/div>\r\n<!--\r\n##### SOURCE BEGIN #####\r\n%% Memory Management for Functions and Variables\r\n% People have different ideas about what costs a lot, in terms of memory,\r\n% in MATLAB.  And sometimes people don't know the details.  Today I am\r\n% going to talk about when MATLAB makes copies of data, for both calling\r\n% functions, and for data stored in variables. MATLAB makes copies of\r\n% arrays it passes only when the data referred to changes (this is called\r\n% copy on write or lazy copying).  \r\n%% Passing Arrays to Functions\r\n% The question is, when does MATLAB copy memory when passing arrays to\r\n% functions.  Some users think that because MATLAB behaves as if data are\r\n% passed by value (as opposed to by reference), that MATLAB always makes\r\n% copies of the inputs when calling a function.  This is not necessarily\r\n% true.  Take a look at this function.\r\ntype fred1\r\n%%\r\n% In |fred1|, the first and third inputs, |x| and |b|, are not altered\r\n% inside.  MATLAB recognizes this and passes both these variables in\r\n% without making any extra copies.  This can be a big memory savings, for\r\n% example, if |x| is a large dataset.  However, in |fred1|, we can see that\r\n% the second input, |a|, gets modified inside.  MATLAB recognizes when this\r\n% is happening to a variable and makes a copy of it to work with so that\r\n% the original variable in the calling workspace is not modified.\r\n%% Structures and Memory\r\n% Each structure member is treated as a\r\n% separate array in MATLAB. This means that if you modify one member of a\r\n% structure, the other members, which are unchanged, are not copied.  It's\r\n% time for an illustration here.\r\n%%\r\n%% Create some rgb image data with 3 planes: red, green, and blue.\r\nim1.r = rand(300,300);\r\nim1.g = rand(300,300);\r\nim1.b = rand(300,300);    \r\n%% \r\n% Instead, rearrange the same data so that we have an array of structs\r\n% each element containing an |[r g b]|-triplet.\r\nim2(300,300).rgb = [0 0 0];  % preallocate the array\r\nfor r = 1:300\r\n    for c = 1:300\r\n        im2(r,c).rgb = [im1.r(r,c) im1.g(r,c) im1.b(r,c)];\r\n    end\r\nend\r\n%%\r\n% Let\u00e2\u20ac\u2122s compare |im1| and |im2|.\r\nclear c r  % tidy up the workspace\r\nwhos\r\n%%\r\n%\r\n% |im1| is a scalar structure with members that hold m x n arrays.\r\n%\r\n% *  |im1.r| = imageRedPlane            REPLACE_WITH_DASH_DASH- size m x n\r\n% *  |im1.g| = imageGreenPlane          REPLACE_WITH_DASH_DASH- size m x n\r\n% *  |im1.b| = imageBluePlane           REPLACE_WITH_DASH_DASH- size m x n\r\n%\r\n% |im1| is size 1 x 1; total # of arrays inside |im1|: 3\r\n%%\r\n% |im2| is an m x n structure array with fields containing 3-element\r\n% vectors.\r\n%\r\n% * |im2(i,j).rgb| = imageOneRGBPixel  REPLACE_WITH_DASH_DASH- size 1 x 3\r\n% \r\n% |im2| is size m x n; total # of arrays inside |im2|: m x n\r\n% \r\n%%\r\n% Notes: Every MATLAB array allocates a header with information. This makes\r\n% |im1| more memory-efficient than |im2| (more generally, scalar structs\r\n% containing arrays are more memory-efficient than a struct array). When\r\n% one field in a structure is changed, and possibly copied, the other\r\n% fields are left intact. \r\ns.A = rand(3);\r\ns.B = magic(3);\r\nsNew = s;\r\nsNew.A(3) = 14;\r\n%%\r\n% Since |s| and |sNew| have unaltered copies of |B|, the |B| fields share\r\n% memory, but the |A| fields do not.\r\n% See the documention section titled \r\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/techdoc\/matlab_prog\/f8-774052.html Using Memory Efficiently>\r\n% for more information.  \r\n%% What's Your Mental Model for MATLAB Memory Management?\r\n% Say that three times fast!\r\n%\r\n% Does the description here and\/or in the documentation change your model?\r\n% \r\n% <http:?p=36\/Respond Let me know.>\r\n%\r\n##### SOURCE END #####\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n   \r\n      People have different ideas about what costs a lot, in terms of memory, in MATLAB.  And sometimes people don't know the details.\r\n         Today I am going to talk about when MATLAB... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2006\/05\/10\/memory-management-for-functions-and-variables\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[7,5],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/36"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=36"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/36\/revisions"}],"predecessor-version":[{"id":2272,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/36\/revisions\/2272"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=36"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=36"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=36"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}