Я использую следующий класс GCM для отправки данных для отправки уведомления GCM около 10000 андроида устройств:пост HttpWebRequest в C# использует большой объем памяти
class GCMandroid
{
private JArray RegIDs;
private string tickerText;
private string level;
private string id;
private string title;
private string message;
private string date;
public GCMandroid(List<string> Ids,string tickerText,string level,string id,
string title,string message,string date)
{
this.RegIDs = new JArray(Ids.ToArray());
this.tickerText = tickerText;
this.level = level;
this.id = id;
this.date = date;
this.title = title;
this.message = message;
}
public string GetPostData()
{
string postData =
"{ \"registration_ids\": " + this.RegIDs + ", " +
"\"time_to_live\":" + "43200" + ", " +
"\"collapse_key\":\"" + "Key" + "\", " +
"\"data\": {\"tickerText\":\"" + this.tickerText + "\", " +
"\"level\":\"" + this.level + "\", " +
"\"id\":\"" + this.id + "\", " +
"\"date\":\"" + this.date + "\", " +
"\"title\":\"" + this.title + "\", " +
"\"message\": \"" + this.message + "\"}}";
return postData;
}
public bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
public string SendGCMNotification(string apiKey, string postData, string postDataContentType = "application/json")
{
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
//
// MESSAGE CONTENT
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
//
// CREATE REQUEST
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");
Request.Method = "POST";
Request.KeepAlive = false;
Request.ContentType = postDataContentType;
Request.Headers.Add(string.Format("Authorization: key={0}", apiKey));
Request.ContentLength = byteArray.Length;
Stream dataStream = Request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
//
// SEND MESSAGE
try
{
WebResponse Response = Request.GetResponse();
HttpStatusCode ResponseCode = ((HttpWebResponse)Response).StatusCode;
if (ResponseCode.Equals(HttpStatusCode.Unauthorized) || ResponseCode.Equals(HttpStatusCode.Forbidden))
{
var text = "Unauthorized - need new token";
}
else if (!ResponseCode.Equals(HttpStatusCode.OK))
{
var text = "Response from web service isn't OK";
}
StreamReader Reader = new StreamReader(Response.GetResponseStream());
string responseLine = Reader.ReadToEnd();
Reader.Close();
Response.Close();
return responseLine;
}
catch (Exception e)
{
}
return "error";
}
}
это используется в форме окна, которые содержат таймер и каждые 10 секунд будут тикать фон рабочий, если он не занят, чтобы получить данные из базы данных и отправить его до 10 000 Android устройств с вызова:
GCMandroid gcm = new GCMandroid(sublist, tickerText, level, id, title, message,date);
gcm.SendGCMNotification(AndroidApiKey, gcm.GetPostData());
где sublist
составляет не более 1000, как гсм облака квоты на каждый запрос. уведомление получено хорошо, но в программах используется большой объем памяти.
после удаления функций при попытке обнаружить основную часть проекта, которая вызывает использование плунжера (2 ГБ памяти, используемой процессом за 4 дня). Я обнаружил, что отправка уведомления вызывает это использование плунжера.
Я искал проблемы использования ram с помощью httpwebrequset и не нашел ничего связанного. Я также пытался вызвать сборщик мусора, но он не очищает всю память, большая часть которой используется; он очищает только около 5% от общей используемой памяти оперативной памяти. Может ли кто-нибудь помочь остановить это использование большой памяти.
Нет ничего явно неправильного в SendGCMNotification(), я предполагаю, что утечка (если она есть) вызвана чем-то другим в приложении. Вам нужно объяснить, как вы пришли к выводу, что «я обнаружил, что отправка уведомления вызывает это использование бара». Кроме того, почему вы вызываете ServicePointManager.ServerCertificateValidationCallback каждый раз? – gooid
Обязательно избавляйтесь от всего, что доступно. Например, ваш Stream, StreamReader и WebResponse. Самая безопасная ставка заключается в следующем: 'using (Stream dataStream = Request.GetRequestStream()) {...}' –
@gooid Я запускаю приложение без отправки уведомления в течение 3-4 дней, а используемая память остается около 20-25 МБ, когда Я запускаю его с отправкой уведомления о возникшей проблеме. – kingk110