Flutter 关于Dart内存策略的问题

Flutter 关于Dart内存策略的问题,flutter,memory,Flutter,Memory,假设您有以下代码 List files=[file1,file2,file3,file4]; 每个文件的大小为10mb 那么它将使用多少内存呢?这听起来很简单,但令人困惑 它将使用40mb。因为它有4个10mb的文件 我不太清楚,但我将使用小于40mb的内存。这是因为内存的使用量不如文件的实际大小,而是指向文件内存地址的指针的大小 1或2?Dart对int或String等基本类型使用pass-by-value,对List等更复杂的数据类型使用pass-by-reference。这里的文件可

假设您有以下代码

List files=[file1,file2,file3,file4];
每个文件的大小为10mb

那么它将使用多少内存呢?这听起来很简单,但令人困惑

  • 它将使用40mb。因为它有4个10mb的文件

  • 我不太清楚,但我将使用小于40mb的内存。这是因为内存的使用量不如文件的实际大小,而是指向文件内存地址的指针的大小


  • 1或2?

    Dart对
    int
    String
    等基本类型使用
    pass-by-value
    ,对
    List
    等更复杂的数据类型使用
    pass-by-reference
    。这里的文件可能是一个对象,因此它将占用指针的内存

    这是传递值的一个简单示例

    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
    }
    
    这里,值“x”通过值传递,因此,即使函数增加了x,主函数中的值仍将保持为1

    通过引用传递的示例:

    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]
    }
    
    void main(){
    无效地址列表(列表x){
    x、 增加(12);
    打印(“这里的x是$x”);
    }
    列表x=[1,2,3,4,5];
    addList(x);//这里是[1,2,3,4,5,12]
    打印(x);//[1,2,3,4,5,12]
    }
    
    这里x的值是通过引用传递的,因此它也会在主函数中得到更新

    传递引用意味着传递内存位置,而不是实际值,这在大列表、数组甚至复杂对象的情况下非常有效。它可以比传递值节省更多的内存

    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
    }
    

    在本例中,
    文件
    变量是
    文件
    (列表)对象的列表。这意味着file1、file2等是
    文件
    对象,因此应在dart中通过引用传递

    当前接受的答案不正确。Dart总是存在的,它是否存在与这个问题无关

    现在回答你的问题。处理文件时使用的内存量取决于处理文件的方式。您显示的示例是文件句柄列表,而不是文件本身。仅通过使用
    文件
    对象实例化对文件的引用,将文件内容加载到内存中是低效的

    因此,您的列表是一个文件句柄列表。这使得您提出的两种解释都不正确,因为数据没有加载到内存中,尽管第二种解释是正确的。该文件的内容不在内存中,因此对于4个10 MB的文件,它不会使用40 MB的内存。它也不是指向内存的指针。指针仍然会指示文件数据在内存中,而您
    file
    对象只是该块的地址。更准确的说法是,它是对操作系统提供的文件的引用,或者是对文件在存储中的位置的引用。文件句柄将占用的内存量相对较小,尽管我不知道确切的值


    如果您使用如下函数显式请求数据,则数据将加载到内存中。然后,整个文件将被加载到内存中,每个文件可能会占用全部10 MB的空间。可能有一些优化我不知道,但它将更接近文件的完整大小。当然,这将在一个单独的变量中,
    文件
    对象本身将占用很少的内存。

    Dart对
    int
    String
    等基本类型使用
    传递值
    ,对
    列表
    等更复杂的数据类型使用
    传递引用
    。文件可能在这里一个对象,因此它将占用pointers@VirajD您还可以分享
    传递值/参考
    部分的参考吗?我已经发布了关于您的查询的答案@iDecode@iDecodeVirag是不正确的。省道总是按值传递。谢谢你的回答。但是,它不像原语是
    按值传递
    和其他
    按引用传递
    <代码>列表是Dart中的特例。创建
    列表时,它将在内存中创建,并且该列表(除非使用
    List.xxx
    类型构造函数复制)将由其他成员共享或直接使用。对于非原始数据类型,例如
    ,它不使用
    按引用传递
    ,除非它是使用
    const
    关键字创建的。从设备相册加载图像时是否应用相同的逻辑?它使用的内存是否与图像大小一样多,但是内存和指针大小一样多?假设我从设备相册加载图像。那么,我会像使用这些图像一样使用内存吗?或者它使用的内存和指向该图像的指针一样多?这个答案不准确。飞镖永远是最好的选择。这与这个问题也完全无关。无论对象是按引用传递还是按值传递,
    文件
    对象都是文件的句柄。它既不是指向文件的“指针”,也不直接占用内存,因为它不存在于内存中。文件中的数据只有在您明确要求使用可用方法通过文件句柄加载到内存中时才会加载。@haedong jeon请参阅我的上述评论。这个答案是不准确的。当你使用
    File
    constructor时,它不会将文件加载到内存中,但你第一段的最后一行表示了其他内容。很好的解释@iDecode不确定您指的是哪一行。我的第一段只提到传递值。
    仅通过使用file对象实例化对文件的引用,将文件内容加载到内存中是低效的。
    --这是one@iDecode上面说“会的”。这解释了为什么情况并非如此。我从没说过这会发生。啊,我明白了。谢谢你的解释:)我糟糕的英语水平把我带到了一个不同的方向。