【问题标题】:System.OutOfMemoryException was thrown. at Go60505(RegexRunner ) at System.Text.RegularExpressions.CompiledRegexRunner.Go()System.OutOfMemoryException 被抛出。在 Go60505(RegexRunner) 在 System.Text.RegularExpressions.CompiledRegexRunner.Go()
【发布时间】:2011-02-07 02:03:37
【问题描述】:

我是一名 c# 开发人员,正在为 vb.net 中的网站编写一些代码。我们在 32 位 iss 6 win 2003 机器上使用了大量缓存,在某些情况下会遇到 OutOfMemoryException 异常。这是我追溯的代码,想知道其他人是否有这个...

Public Sub CreateQueryStringNodes()
    'Check for nonstandard characters'
    Dim key As String
    Dim keyReplaceSpaces As String
    Dim r As New Regex("^[-a-zA-Z0-9_]+$", RegexOptions.Compiled)

    For Each key In HttpContext.Current.Request.Form
        If Not IsNothing(key) Then
            keyReplaceSpaces = key.Replace(" ", "_")
            If r.IsMatch(keyReplaceSpaces) Then
                CreateNode(keyReplaceSpaces, HttpContext.Current.Request(key))
            End If
        End If
    Next

    For Each key In HttpContext.Current.Request.QueryString
        If Not IsNothing(key) Then
            keyReplaceSpaces = key.Replace(" ", "_")

            If r.IsMatch(keyReplaceSpaces) Then
                CreateNode(keyReplaceSpaces, HttpContext.Current.Request(key).Replace("--", "-"))
            End If
        End If
    Next
End Sub

.NET 框架版本:2.0.50727.3053; ASP.NET 版本:2.0.50727.3053

错误:

引发了“System.OutOfMemoryException”类型的异常。在 Go60505(RegexRunner) 在 System.Text.RegularExpressions.CompiledRegexRunner.Go() 在 System.Text.RegularExpressions.RegexRunner.Scan(正则表达式,字符串 文本,Int32 textbeg,Int32 textend,Int32 textstart,Int32 prevlen, 布尔快速)在 System.Text.RegularExpressions.Regex.Run(Boolean 快速,Int32 prevlen,字符串输入,Int32 开头,Int32 长度, Int32 startat) 在 System.Text.RegularExpressions.Regex.IsMatch(String 输入)在 Xcite.Core.XML.Write.CreateQueryStringNodes() 在 Xcite.Core.XML.Write..ctor(String IncludeSessionAndPostedData) 在 mysite._Default.Page_Load(Object sender, EventArgs e) at System.Web.UI.Control.OnLoad(EventArgs e) 在 System.Web.UI.Control.LoadRecursive() 在

谢谢

【问题讨论】:

    标签: c# .net vb.net


    【解决方案1】:

    有一个couplearticlesthere 几乎说避免使用Compiled,它并不真正意味着人们有时认为它意味着什么。如果我理解正确,使用 Compiled 实际上会在应用程序期间永久占用内存。由于您在 Web 上,因此应用程序的生命周期可能相当长。这应该在 2.0 框架中得到修复/解决,但看起来没有。

    【讨论】:

    • 正则表达式可以设为静态:Private Shared r As New Regex("^[-a-zA-Z0-9_]+$", RegexOptions.Compiled),以避免每次调用 CreateQueryStringNodes 时都发出代码。
    • @0xA3,也可以指出。我刚刚针对 Dim/Static RegEx 声明运行了 10,000 个循环的循环,Dim 需要 14 秒才能完成,而 Static 需要 6 毫秒 才能完成。我希望更多人知道何时使用静态变量。
    • 你引用 Coding Horror...我相信他在谈论 .Net 1.0 和 1.1。 2.0 及更高版本的做法有所不同。引用 MSDN (msdn.microsoft.com/en-us/library/…Class) 在 .NET Framework 1.0 和 1.1 版本中,所有编译的正则表达式,无论它们是用于实例还是静态方法调用,都会被缓存。从.NET Framework 2.0,只缓存静态方法调用中使用的正则表达式。
    • @OmegaMan,这实际上也是另一个不同的优点。实例方法没有获得 RegEx 缓存的好处,只有静态方法可以(这对我来说是违反直觉的)。下面是一篇文章,解释了他们修复了内存问题,但仍然建议避免编译:“因此,编译正则表达式的一般方法应该是只将此模式用于您知道将重复使用的有限表达式集。甚至更多具体来说,除了一两个键正则表达式外,请避免使用此模式..." msdn.microsoft.com/en-us/magazine/cc163670.aspx#S7
    • 在一定程度上我同意这篇文章和你的 cmets,但由于 OP 在两个单独的紧密循环中调用了正则表达式处理,因此内存占用和前期加载是值得的成本,因为我们不知道实际调用此方法的频率....恕我直言:我通常使用静态方法并会重写代码,从而获得缓存机制的好处。
    【解决方案2】:

    谢谢!让我明天在办公室检查一些东西,我可能会尝试两种解决方案的组合 - 我会写一些测试并让你知道。正则表达式解析器作用于一个长字符串,创建节点正在填充一个列表对象,该对象稍后会像 xml 一样用于 html 输出的 xslt 转换,我们在最终输出上使用响应输出缓存。 我不认为静态变量会有所作为,因为这是一个 asp.net 应用程序,CreateQueryStringNodes 在每个页面的页面生命周期中只调用一次。我可能会将其放入应用缓存并将其用作单例,但获取它的工作可能效率较低 - 让我测试一下...

    再次感谢。

    【讨论】:

      【解决方案3】:

      所以一旦代码用'_'替换了所有空格,它就会匹配它们?这是对带有破折号或下划线的字母数字的某种验证吗?

      正则表达式解析器正在处理多少数据?

      请注意,您的模式(就像现在一样)可以更改为

      ^[\w-_]+$

      (请注意,您使用 Regex Compiled 非常适合这种情况,不像其他帖子所说的那样)。

      要了解编译检查,请查看正则表达式编译部分的Base Class Library Performance Tips and Tricks。高温

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-28
        • 2019-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-17
        相关资源
        最近更新 更多