某些时间戳值引发系统内存不足异常
Posted
技术标签:
【中文标题】某些时间戳值引发系统内存不足异常【英文标题】:Throwing System out of memory exception for certain values of timestamps 【发布时间】:2017-08-08 17:47:13 【问题描述】:我在 ASP.net 中有一个网站,使用 Vb.net 作为其背后的代码,当我尝试在网格视图中检索数据时,它会针对某些时间戳值抛出错误。可能是什么问题呢?错误是系统内存不足,网站托管在 IIS 服务器上。
我后面的代码如下:
Inherits System.Web.UI.Page
Public dad As OleDbDataAdapter
Protected Sub Page_Load(ByVal sender As Object, e As EventArgs) Handles Me.Load
End Sub
Protected Sub TextBox2_TextChanged(sender As Object, e As EventArgs) Handles TextBox2.TextChanged
End Sub
Protected Sub TextBox3_TextChanged(sender As Object, e As EventArgs) Handles TextBox3.TextChanged
End Sub
Protected Sub btnSave_Click1(ByVal sender As Object, ByVal e As EventArgs) Handles Button2.Click
Dim connectionString As [String] = "Provider=Microsoft.ACE.OLEDB.12.0;Data" + " Source=C:\Program Files (x86)\GL Communications Inc\DataImport\VQT.mdb"
Dim ds As New DataSet()
Dim conn As New OleDbConnection(connectionString)
conn.Open()
Dim cmd As New OleDbCommand("SELECT ROUND(AVG(POLQA_Score),3) AS mean_POLQA_score FROM VQTPOLQA WHERE VQT_Timestamp BETWEEN ? AND ? AND VQuad_PhoneID =?", conn)
Dim cmd2 As New OleDbCommand("SELECT ROUND(Stdev(POLQA_score),3) AS stdev_POLQA_score FROM VQTPOLQA WHERE VQT_Timestamp BETWEEN ? AND ? AND VQuad_PhoneID=?", conn)
Dim cmd3 As New OleDbCommand("SELECT ROUND(AVG(RTD),3) AS mean_RTD FROM VQuadData WHERE VQuad_Timestamp BETWEEN ? AND ? AND RTD>0 AND VQuad_PhoneID=?", conn)
Dim cmd4 As New OleDbCommand("SELECT ROUND(Stdev(RTD),3) AS STDEV_RTD FROM VQuadData WHERE VQuad_Timestamp BETWEEN ? AND? AND RTD>0 AND VQuad_PhoneID=?", conn)
Dim param As OleDbParameter
param = cmd.CreateParameter
param.OleDbType = OleDbType.Date
param.Value = DateTime.Parse(TextBox3.Text)
param.ParameterName = "@StartDate"
cmd.Parameters.Add(param)
Dim param1 As OleDbParameter
param1 = cmd.CreateParameter
param1.OleDbType = OleDbType.Date
param1.Value = DateTime.Parse(TextBox2.Text)
param1.ParameterName = "@EndDate"
cmd.Parameters.Add(param1)
GridView1.DataBind()
Dim param2 As OleDbParameter
param2 = cmd2.CreateParameter
param2.OleDbType = OleDbType.Date
param2.Value = DateTime.Parse(TextBox3.Text)
param2.ParameterName = "@StartDate"
cmd2.Parameters.Add(param2)
Dim param3 As OleDbParameter
param3 = cmd2.CreateParameter
param3.OleDbType = OleDbType.Date
param3.Value = DateTime.Parse(TextBox2.Text)
param3.ParameterName = "@EndDate"
cmd2.Parameters.Add(param3)
GridView2.DataBind()
Dim param4 As OleDbParameter
param4 = cmd3.CreateParameter
param4.OleDbType = OleDbType.Date
param4.Value = DateTime.Parse(TextBox3.Text)
param4.ParameterName = "@StartDate"
cmd3.Parameters.Add(param4)
Dim param5 As OleDbParameter
param5 = cmd3.CreateParameter
param5.OleDbType = OleDbType.Date
param5.Value = DateTime.Parse(TextBox2.Text)
param5.ParameterName = "@EndDate"
cmd3.Parameters.Add(param5)
GridView3.DataBind()
Dim param6 As OleDbParameter
param6 = cmd4.CreateParameter
param6.OleDbType = OleDbType.Date
param6.Value = DateTime.Parse(TextBox3.Text)
param6.ParameterName = "@StartDate"
cmd4.Parameters.Add(param6)
Dim param7 As OleDbParameter
param7 = cmd4.CreateParameter
param7.OleDbType = OleDbType.Date
param7.Value = DateTime.Parse(TextBox2.Text)
param7.ParameterName = "@EndDate"
cmd4.Parameters.Add(param7)
GridView4.DataBind()
conn.Close()
End Sub
Protected Sub DropDownList1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles DropDownList1.SelectedIndexChanged
End Sub
Private Sub ClearControls(ByVal control As Control)
For i As Integer = control.Controls.Count - 1 To 0 Step -1
ClearControls(control.Controls(i))
Next
If Not (TypeOf control Is TableCell) Then
If control.[GetType]().GetProperty("SelectedItem") IsNot Nothing Then
Dim literal As New LiteralControl()
control.Parent.Controls.Add(literal)
Try
literal.Text = DirectCast(control.[GetType]().GetProperty("SelectedItem").GetValue(control, Nothing), String)
Catch
End Try
control.Parent.Controls.Remove(control)
ElseIf control.[GetType]().GetProperty("Text") IsNot Nothing Then
Dim literal As New LiteralControl()
control.Parent.Controls.Add(literal)
literal.Text = DirectCast(control.[GetType]().GetProperty("Text").GetValue(control, Nothing), String)
control.Parent.Controls.Remove(control)
End If
End If
Return
End Sub
Protected Sub Button3_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button3.Click
Dim dt As New DataTable("GridView_Data")
For Each cell As TableCell In GridView5.HeaderRow.Cells
dt.Columns.Add(cell.Text)
Next
For Each row As GridViewRow In GridView5.Rows
dt.Rows.Add()
For i As Integer = 0 To row.Cells.Count - 1
dt.Rows(dt.Rows.Count - 1)(i) = row.Cells(i).Text
Next
Next
Dim wb As New XLWorkbook
wb.Worksheets.Add(dt)
Response.Clear()
Response.Buffer = True
Response.Charset = ""
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Response.AddHeader("content-disposition", "attachment;filename=GridViewPOLQA.xlsx")
Using MyMemoryStream As New MemoryStream()
wb.SaveAs(MyMemoryStream)
MyMemoryStream.WriteTo(Response.OutputStream)
Response.Flush()
Response.[End]()
End Using
End Sub
Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
Return
End Sub
Protected Sub Button4_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button4.Click
Dim dt As New DataTable("GridView_Data")
For Each cell As TableCell In GridView6.HeaderRow.Cells
dt.Columns.Add(cell.Text)
Next
For Each row As GridViewRow In GridView6.Rows
dt.Rows.Add()
For i As Integer = 0 To row.Cells.Count - 1
dt.Rows(dt.Rows.Count - 1)(i) = row.Cells(i).Text
Next
Next
Dim wb As New XLWorkbook
wb.Worksheets.Add(dt)
Response.Clear()
Response.Buffer = True
Response.Charset = ""
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Response.AddHeader("content-disposition", "attachment;filename=GridViewRTD.xlsx")
Using MyMemoryStream As New MemoryStream()
wb.SaveAs(MyMemoryStream)
MyMemoryStream.WriteTo(Response.OutputStream)
Response.Flush()
Response.[End]()
End Using
End Sub
Public Shared Sub ExportToExcel(data As IEnumerable(Of Dynamic), sheetName As String)
Dim wb As New XLWorkbook()
Dim ws = wb.Worksheets.Add(sheetName)
ws.Cell(2, 1).InsertTable(data)
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
HttpContext.Current.Response.AddHeader("content-disposition", [String].Format("attachment;filename=0.xlsx", sheetName.Replace(" ", "_")))
Using memoryStream As New MemoryStream()
wb.SaveAs(memoryStream)
memoryStream.WriteTo(HttpContext.Current.Response.OutputStream)
memoryStream.Close()
End Using
HttpContext.Current.Response.[End]()
End Sub
这是我得到的错误堆栈跟踪,如下所述。
[OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.]
System.Convert.ToBase64String(Byte[] inArray, Int32 offset, Int32 length, Base64FormattingOptions options) +119
System.Web.UI.ObjectStateFormatter.Serialize(Object stateGraph, Purpose purpose) +229
System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter2.Serialize(Object state, Purpose purpose) +13
System.Web.UI.Util.SerializeWithAssert(IStateFormatter2 formatter, Object stateGraph, Purpose purpose) +40
System.Web.UI.HiddenFieldPageStatePersister.Save() +106
System.Web.UI.Page.SavePageStateToPersistenceMedium(Object state) +108
System.Web.UI.Page.SaveAllState() +653
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5314
web.config文件如下:-
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<connectionStrings>
<add name="ConnectionString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="|DataDirectory|\VQT_GL Testing.mdb""
providerName="System.Data.OleDb" />
<add name="ConnectionString2" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="|DataDirectory|\VQT_GL Testing.mdb""
providerName="System.Data.OleDb" />
<add name="ConnectionString3" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="|DataDirectory|\VQT_GL Testing.mdb""
providerName="System.Data.OleDb" />
<add name="ConnectionString4" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="|DataDirectory|\VQT_GL Testing.mdb""
providerName="System.Data.OleDb" />
<add name="ConnectionString5" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="|DataDirectory|\VQT_GL Testing.mdb""
providerName="System.Data.OleDb" />
<add name="ConnectionString6" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="|DataDirectory|\VQT_GL Testing.mdb""
providerName="System.Data.OleDb" />
<add name="VQTConnectionString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="C:\Program Files (x86)\GL Communications Inc\DataImport\VQT.mdb""
providerName="System.Data.OleDb" />
</connectionStrings>
<system.web>
<compilation debug="false" strict="false" explicit="true" targetFramework="4.5.2" />
<customErrors mode="Off"/>
<authentication mode="None"/>
<httpRuntime targetFramework="4.5.2" maxRequestLength="1048576" executionTimeout="3600" />
<machineKey
validationKey="62AFB48AEFD48352027301E7D1E6180E95AFF287377B03FA4492404998D3C1ADD2EBB9C8D18DD4A87E53759167ADC385AE29CC3B0F12965B4D68A4964D0F8062"
decryptionKey="A4E89B2AA3F120979F154A5EFCF4F4254A1925B59285A2A9"
validation="SHA1" decryption="AES"
/>
</system.web>
<system.webServer>
<security>
<requestFiltering>
<!--The default size is 30000000 bytes (28.6 MB). MaxValue is 4294967295 bytes (4 GB)-->
<!-- 100 MB in bytes -->
<requestLimits maxAllowedContentLength="104857600" />
</requestFiltering>
</security>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<appSettings>
<add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />
</appSettings>
</configuration>
【问题讨论】:
您将多少行拉入您的 GridView? @chakeda 它根据自定义时间戳值,但我在 gridview 上只显示一个值,所以它是一行 您使用的是什么 Excel 库?您是否尝试过在完成后关闭工作簿? @JohnWu Excel 我正在使用 ClosedXML.Excel 但网站本身在更长的时间戳期间崩溃 【参考方案1】:当您以管理员身份在服务器上运行 cmd 提示符时,必须使用iisreset/ stop
和iisreset/ start
命令来刷新内存使用情况。
【讨论】:
【参考方案2】:在 ClosedXML 中,XLWorkbook
是一次性的,因此您应该在 Using 块中使用它。如果您不这样做,工作簿对象将继续占用内存并最终给您随机的 OutOfMemoryExceptions。我的猜测是与时间戳值的关系是巧合。
Using wb As New XLWorkbook
wb.Worksheets.Add(dt)
Response.Clear()
Response.Buffer = True
Response.Charset = ""
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Response.AddHeader("content-disposition", "attachment;filename=GridViewPOLQA.xlsx")
wb.SaveAs(Response.OutputStream)
Response.Flush()
End Using
另外,do not use Response.End。
另外,我摆脱了 MemoryStream。您可以直接写入 OutputStream。
【讨论】:
现在它给出了这个错误堆栈跟踪 [CryptographicException: Error occurred during a cryptographic operation.] 您应该开始另一个问题,包括堆栈跟踪和其他重要的故障排除信息。以上是关于某些时间戳值引发系统内存不足异常的主要内容,如果未能解决你的问题,请参考以下文章
虚拟内存地址空间不足(Borland C++ Builder 6 程序)