0

Suppose you have the following code.

List<File> files = [file1, file2, file3, file4];

Each file is 10mb in size.

So how much memory will it use? It sounds simple, but it's confusing.

  1. It will use 40mb. Because it had 4 10mb files.

  2. I don't know exactly, but I'll use much less than 40mb.This is because memory is not used as much as the actual size of the file, but as much as the size of a pointer pointing to the memory address of the file.

1 or 2?

Christopher Moore
  • 15,626
  • 10
  • 42
  • 52
  • Dart uses `pass by value` for primitive types like `int` or `String` and uses `pass by reference` for more complex data types like `List`.Here the files are probably an object so it will take on the memory of the pointers – Viraj Doshi Mar 31 '21 at 07:26
  • @VirajD Can you also share the references for `pass by value/reference` part? – iDecode Mar 31 '21 at 07:39
  • I have posted an answer regarding your query @iDecode – Viraj Doshi Mar 31 '21 at 08:22
  • 1
    @iDecode Virag is incorrect. Dart is always pass-by-value. https://stackoverflow.com/questions/25170094/what-is-the-true-meaning-of-pass-by-reference-in-modern-languages-like-dart – Christopher Moore Mar 31 '21 at 14:20

2 Answers2

2

The currently accepted answer is incorrect. Dart is always pass-by-value and whether it is or not is irrelevant to this question.

Now for your question. The amount of memory that you're using when working with files depends on what you're doing with them. The example you show is a list of file handles, not the files themselves. It would be inefficient to load the contents of a file into memory just by instantiating a reference to the file with a File object.

So your list is a list of file handles. This makes both of your proposed explanations incorrect since the data is not loaded into memory, though you're on the right track with the second explanation. The contents of the file is not in memory, so it will not use 40 MB of memory for 4 10 MB files. It's also not a pointer to the memory either. A pointer would still indicate that the file data is in memory and you File object just an address for that block. It's more accurate to says that it's a reference to the file given by the OS or a reference to the file's place in storage. The amount of memory that the file handle will take up is going to be relatively small, though I don't know any exact values.

Data will be loaded into memory if you explicitly request that data with a function like readAsBytes. Then the whole file will be loaded into memory and it will likely use the full 10 MB per file. There might be some optimization I don't know about, but it will be closer to the full size of the file. This will of course be in a separate variable and the File objects themselves will take up very little memory.

Christopher Moore
  • 15,626
  • 10
  • 42
  • 52
  • When you use `File` constructor, it doesn't load the file in the memory, but your first paragraph's last line says something else. Nice explanation though! – iDecode Apr 01 '21 at 06:23
  • @iDecode Not sure which line you're referring to. My first paragraph only mentions pass-by-value. – Christopher Moore Apr 01 '21 at 14:04
  • `It would be inefficient to load the contents of a file into memory just by instantiating a reference to the file with a File object.` -- This one – iDecode Apr 01 '21 at 14:43
  • @iDecode That says "It would be". It's an explanation for why that is not the case. I never said that this actually happens. – Christopher Moore Apr 01 '21 at 14:47
  • Ahh I got that. Thanks for explaining :) My poor English skills took me to a different direction. – iDecode Apr 01 '21 at 14:48
-2

Dart uses pass-by-value for primitive types like int or String and uses pass-by-reference for more complex data types like List. Here the files are probably an object so it will take on the memory of the pointers.

This is a simple example for pass-by-value.

void main() {
  void addOne(int x) {
    x += 1;
    print("x here is $x");
  }
  
  int x = 1;
  addOne(x); //Output: "x here is 2"
  print(x); //1
}

Here the value "x" is passed by value so, even if the function incremented x, the value in the main function will still remain 1.

example for pass-by-reference:

void main() {
  void addList(List<int> x) {
    x.add(12);
    print("x here is $x");
  }

  List<int> x = [1, 2, 3, 4, 5];
  addList(x);  //x here is [1, 2, 3, 4, 5, 12]
  print(x);  //[1, 2, 3, 4, 5, 12]
}

Here the value of x is passed by reference so it would get updated in the main function as well

Passing the reference means to pass the memory location and not the actual value which is very efficient in case of big list or arrays or even complex objects. It can save much more memory than pass-by-value.

In your case the files variable is a List of File(List<File>) objects. That means that file1, file2, etc are File objects and shall thus be passed-by-reference in dart

Viraj Doshi
  • 771
  • 6
  • 26
  • Thanks for the answer. However, it isn't like primitives are `pass by value` and other `pass by reference`. `List` is a special case in Dart. When you create a `List`, it's created in the memory and that list (unless copied using `List.xxx` type constructors) is shared or used directly by other members. Same thing goes for non-primitive data types say a `Class` for example, it doesn't use `pass by reference` unless it was created using `const` keyword. – iDecode Mar 31 '21 at 08:44
  • Does the same logic apply when loading images from device albums?Is it not using memory as much as the size of the image, but as much memory as the size of the pointer? – haedong-jeon Mar 31 '21 at 09:18
  • Suppose I load the images from a device album. So am I going to use memory as much as those images? Or does it use as much memory as a pointer to that image? – haedong-jeon Mar 31 '21 at 09:20
  • This answer is inaccurate. Dart is *always* [pass-by-value](https://stackoverflow.com/questions/25170094/what-is-the-true-meaning-of-pass-by-reference-in-modern-languages-like-dart). That's also **completely** irrelevant for this question. Whether objects are pass-by-reference or by value, the `File` object is a *handle* to the file. It's neither a "pointer" to the file or directly take up memory as it does not exist in memory. The data from the file is only loaded into memory once you *specifically request* that that be done *through* the file handle with the methods available. – Christopher Moore Mar 31 '21 at 14:19
  • @haedong-jeon Please see my above comment. This answer is inaccurate. – Christopher Moore Mar 31 '21 at 14:19
  • @haedong-jeon Please see my answer. It corrects some inaccuracies presented in this one. – Christopher Moore Mar 31 '21 at 14:38