• 第十二节:预测需求大量的内存的操作能否成功


    实现一个算法时,可能事先知道该算法需要大量内存,而且要占用大量内存。可能就这么开始执行算法,如果内存耗尽,CLR会抛出一个OutOfMemoryException。在这种情况下,以前做的大量工作都算是白费了。另外,需要捕捉这个异常,使程序得体的恢复。

    System.Runtime命名空间提供了一个MemoryFailPoint类,它允许在开始一个内存消耗巨大的算法之前检查是否有充裕的内存。你可以在MSDN上查看该类。

    使用该类的方法非常简单。首先构造该类的一个实例。在构造时,要传递你的算法可能需要的MB数。在内部构造会执行以下检查,按顺序引发相应的行动。

    1. 系统的分页文件是否有足够的可用空间,而且进程中是否有足够的连续虚拟地址空间来满足需求?注意,会扣除已被另一个MemoryFailPoint构造调用逻辑性保留的内存。
    2. 如果没有足够的空间,就强制一次垃圾回收,尝试释放一些空间。
    3. 如果仍然没有足够的分页文件空间,就尝试扩展分页文件,如果分页文件不能扩展到足够大,就抛出一个InsufficientMemoryException
    4. 如果仍然没有连续的虚拟地址空间,就抛出一个InsufficientMemoryException
    5. 如果找到了足够大的分页文件空间和虚拟地址空间,就将兆字节数加到MemoryFailPoint类定义的一个私有静态变量上面,从而保留请求的兆字节数,这种加法操作是以一种线程安全的方式进行的,使多个线程能同时构造该类的实例,并确保只要构造器不抛出异常,就能在逻辑上保留他们请求的内存。

    如果MemoryFailPoint类的构造器抛出一个InsufficientMemoryException,你的应用程序可释放一些它正在使用的资源,或降低它的性能以降低CLR未来跑出InsufficientMemoryException的机率。InsufficientMemoryException是从OutOfMemoryException派生的。

    注意:如果MemoryFailPoint在逻辑上没有抛出异常,表明已经在逻辑上保留了所请求的内存。现在可以开启执行消耗内存大的算法。但要注意,请求的内存尚未物理性的分配。这意味着算法只是更有可能获得所需内存并运行成功。即使构造器没有抛出异常,MemoryFailPoint也不能保证算法获得他所需要的内存。这个类的目的是帮助你写更健壮的应用程序。

    执行完算法之后,要在构造的MemoryFailPoint对象上调用Dispose方法。在内部Dispose会以线程安全的方式从MemoryFailPoint类的静态字段中减去保留的字节数,一下演示了MemoryFailPoint类的用法:

    static void Main(string[] args)

            {

                try

                {

                    using (System.Runtime.MemoryFailPoint mfp = new System.Runtime.MemoryFailPoint(1500))

                    {

                        //在这里执行内存消耗大的算法。

                    }

                }

                catch (InsufficientMemoryException e)

                {

                    Console.WriteLine(e);

                }

            }

  • 相关阅读:
    HTML_表单
    jabc_DAO
    JDBC 加钱减钱
    JDBC 连接池
    JDBC
    视图序列索引
    【Java8】 lambda 特性讲解
    IntelliJ IDEA 常用快捷键
    Java IO 之 装饰模式
    Java IO 讲解
  • 原文地址:https://www.cnblogs.com/bingbinggui/p/4454424.html
Copyright © 2020-2023  润新知