5.1.1. 程序优化¶
5.1.1.1. 提供64位版本¶
寻址能力
32位寻址能力为2的32次方,即4*2^30为4GB。
其中系统分一半内存(系统空间)以便管理与调度系统各应用程序,还剩2GB可有程序使用(用户空间)。
64位寻址能力则为2的64次方,即16*2^60为16EB。
当然这个是理论值,目前Windows的实现+的物理内存是16TB左右,也就是44位。
64位的地址线实际上连64根都不到,只实现了40~50根,因为足够用了,Windows x64版本限制了44位寻址,最大16TB内存,所以造成了所谓的AMD64空洞(用户空间在低位,内核空间在高位,而44位寻址不完全,中间必然有空洞)
.NET内存溢出
处理器/系统 32位操作系统 64位操作系统 32位进程 800-1200 MB 2800 MB 与/ 3GB 32位进程 1800 MB N / A 64位进程 N / A 如果使用的是4 GB的进程或更多,如果更多的内存2800 MB(约的RAM +页面文件70%) x64
项目 - 属性 - 生成 - 目标平台
选择x64
5.1.1.2. DataSet无法及时被GC¶
this.cReportKEY1.EditDataSet.Merge(_ds, false, System.Data.MissingSchemaAction.AddWithKey);
_ds = null;
_ds.Dispose();
GC.Collect();
在_ds.Dispose()前需要显示指定 _ds = null; 以便GC能够及时回收内存
- 容量提升
- 与_ds填充的数据量有关,本案例中容量提升了大约30%,由17万提高到22万(黄永慎测)
- 减少字段数
5.1.1.3. Excel数据导出¶
采用QueryTable方式,直接从数据库中将数据导入到Excel中
- 一分钟可以导出约30万条数据(包含210列)(陈家昌测)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace exportToExcel
{
public partial class Form1 : Form
{
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
int pid = 0;
Excel.Application m_objExcel = null;
public Form1()
{
InitializeComponent();
m_objExcel = new Excel.Application();
GetWindowThreadProcessId(new IntPtr(m_objExcel.Hwnd), out pid);
}
private void button1_Click(object sender, EventArgs e)
{
Stopwatch sw = new Stopwatch();
sw.Start();
string path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "export.xlsx");
string filename = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, Guid.NewGuid() + ".xlsx");
System.IO.File.Copy(path, filename);
query_table_getdata(filename);
Debug.Write(sw.ElapsedMilliseconds);
MessageBox.Show(sw.Elapsed.TotalSeconds.ToString());
}
public void query_table_getdata(string sourpath)
{
Excel.Workbooks m_objBooks = null;
Excel.Workbook m_objBook = null;
Excel.Sheets m_objSheets = null;
Excel.Worksheet m_objSheet = null;
Excel.Range m_objRange = null;
m_objExcel.Visible = true;
string lsConn = "OLEDB;" + @"Provider=SQLOLEDB.1;Data Source=line;uid=sa;Password=******;Initial Catalog=db_hz;Persist Security Info=False;";
string lsSQL = "Select * from mf_pss";
m_objBooks = m_objExcel.Workbooks;
string path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, sourpath);
m_objBook = m_objBooks.Open(path, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel.Worksheet)m_objSheets.get_Item(1);
m_objRange = m_objSheet.get_Range("A2", Type.Missing);
Excel.Range VSTORange = ((Excel.Range)m_objSheet.Cells[1, 1]);
Excel.ListObject ListObject = m_objSheet.ListObjects.Add(Excel.XlListObjectSourceType.xlSrcExternal,
((object)lsConn), false, Excel.XlYesNoGuess.xlYes, VSTORange);
ListObject.QueryTable.CommandText = ((object)lsSQL);
ListObject.QueryTable.RowNumbers = false;
ListObject.QueryTable.FillAdjacentFormulas = false;
ListObject.QueryTable.PreserveFormatting = true;
ListObject.QueryTable.RefreshOnFileOpen = false;
ListObject.QueryTable.BackgroundQuery = true;
ListObject.QueryTable.SavePassword = false;
ListObject.QueryTable.SaveData = true;
ListObject.QueryTable.AdjustColumnWidth = true;
ListObject.QueryTable.RefreshPeriod = 0;
ListObject.QueryTable.PreserveColumnInfo = true;
ListObject.QueryTable.Refresh(false);
m_objBook.Connections[1].Delete();
m_objBook.Save();
// m_objBook.Close(false, Type.Missing, Type.Missing);
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
m_objExcel.Quit();
Process p = Process.GetProcessById(pid);
p.Kill();
}
}
}
|