У меня есть несколько вопросов по поводу утечки памяти.
В моем приложении winForm я использую TabControl
с WebBrowser
объектами, которые я размещаю без проблем.
Мне нужно использовать много List<T>
, и 1 из них должен быть статическим, этоиспользует около 1000 2000 Strings
(url), и его необходимо очищать и обновлять каждые 10 минут, в то время как другой список должен использоваться с новым элементом для каждого цикла.
Теперь я использовал память Dot Trace, чтобы выяснить причину утечки памяти.Это не говорит мне, какая функция вызывает его, для String
он говорит, что не может найти PDB mscorilib.dll, а для Byte[] = Source
не доступен для массива.
> 39,28% System.Byte [] Count = 22 Size = 615819 HeldCount = 22 HeldSize
> = 615819
> 27,06% System.String Count = 6370 Size = 424222 HeldCount = 6370 HeldSize = 424222
3,70% System.Object [] Count = 250 Size = 57992 HeldCount = 6206 HeldSize = 377523
(остальные живые объекты используют 2%3%)
Я читал об утечках памяти в каком-то вопросе о stackoverlow, и одной из многих ошибок является сохранение ссылочной переменной для List (для примера).
Теперь я бы понял: еслиэтот код вызывает утечку памяти 1)
private void ExampleLeaks()
{
List<String> example = new List<String>();
example.add("foo");
example.add("bar");
return example;
}
решение должно быть таким?
Class foo {
List<String> example = new List<String>();
private void ExampleLeaks()
{
example.clear();
example.add("foo");
example.add("bar");
return example;
}
}
2) Теперь я не понимаю, для чего используется byte[]
.Только байт, который я использую, находится в HttpWebRequest
.Я сделал несколько подключений к веб-серверу, где я делаю логин, сохраняю Cookie и каждую 1 минуту использую CookieCollection
от логина для обновления данных.
Я использую этот метод каждую 1 минуту
В основном классе я инициализирую StringBuilder buf = new StringBuilder();
public String DoRequestWeb(String urls, String Method, String user, String data, String License, String Action)
{
Uri url = new Uri(urls);
HttpWebRequest _request = (HttpWebRequest)WebRequest.Create(url);
_request.Method = Method;
_request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
_request.AllowAutoRedirect = false;
_request.CookieContainer = _cookieContainer;
_request.ContentType = "application/x-www-form-urlencoded";
_request.UserAgent = "SomeuserAgent";
_request.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");
string _postData;
_postData = // Do Stuff
byte[] _byteArray = Encoding.UTF8.GetBytes(_postData);
Debug.WriteLine(_byteArray.Count());
_request.ContentLength = _byteArray.Length;
using (Stream _reqStream = _request.GetRequestStream())
{
_reqStream.Write(_byteArray, 0, _byteArray.Length);
_reqStream.Close();
}
buf.Clear();
using (HttpWebResponse _response = (HttpWebResponse)_request.GetResponse())
{
if (HttpStatusCode.OK == _response.StatusCode)
{
Debug.WriteLine("Status code " + _response.StatusCode);
using (StreamReader _reader = new StreamReader(_response.GetResponseStream(), Encoding.UTF8))
{
char[] buffer = new char[256];
int count;
Debug.WriteLine("Buffer [] char count "+(buffer.Count()));
while ((count = _reader.Read(buffer, 0, 256)) > 0)
{
buf.Append(buffer, 0, count);
}
}
}
}
return buf.ToString();
}
И 3)
Может быть, это худшее Функция Когда-либо писала в истории людей, но я не понимаю, как написать это лучше, и возможно это также вызывает утечки памяти.
Все Этот список инициализируется в классе
//response contain a list of 1000 2000 links taken from a
//httpwebRequest and take data from XML Document webpage and parse it into a list
public List<MainForm.Links> GetListaCiclo(List<Links> response3)
{
listGoogle.Clear();
listYahoo.Clear();
listBing.Clear();
listOther.Clear();
//Other 4
var rnd = new Random();
var q = from a in response3.GroupBy(l => new { l.idHost, l.Type })
let col = a.ToList()
select col[rnd.Next(0, col.Count)];
foreach (Links str in q)
{
switch (str.idHost)
{
case 0:
listGoogle.Add(str);
break;
case 1:
listYahoo.Add(str);
break;
case 2:
listBing.Add(str);
break;
case 3
listOther.Add(str);
break;
//Other 4 list
}
}
var google = listGoogle.OrderBy(x => rnd.Next()).Take(4);
var yahoo = listYahoo.OrderBy(x => rnd.Next()).Take(2);
var Bing = listBing.OrderBy(x => rnd.Next()).Take(1);
var otherSeacher = listOtherSeacher.OrderBy(x => rnd.Next()).Take(1);
//Other same 4
tmp.Clear();
tmp = google.Where(h => h != null).ToList();
tmp.AddRange(yahoo.Where(h => h != null));
tmp.AddRange(bing.Where(h => h != null));
tmp.AddRange(other.Where(h => h != null));
.....other 4
return tmp;
}
ОБНОВЛЕНИЕ: 4) Как насчет Pinvoke?
[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
private static extern int UrlMkSetSessionOption(int dwOption, string pBuffer, int dwBufferLength, int dwReserved);
const int URLMON_OPTION_USERAGENT = 0x10000001;
private const int INTERNET_OPTION_END_BROWSER_SESSION = 42;
[DllImport("wininet.dll", SetLastError = true)]
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);
[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);
[DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern IntPtr GetCurrentProcess();
Я просто звоню им 1 раз в минуту.Я не знаю, может ли это привести к утечке памяти.