Случайная ошибка: попытка чтения или записи защищенной памяти

У нас есть приложение С#.Net, использующее службы WCF. И приложение развертывается на нашем производственном сервере под Windows Service Application. Одна часть модуля отвечает за создание файлов формы (*.shp, *.dbf) для меньшей площади, над которой рабочие будут работать сегодня, и отправлять их на КПК.

Чтобы записать файлы формы, мы используем стороннюю dll, NetTopologySuite

GisSharpBlog.NetTopologySuite.IO.ShapefileWriter

который также находится в С#. (я не уверен, использует ли какая-либо ссылка dll неуправляемый код.) В течение некоторого времени система может работать нормально. Затем мы получаем исключение, говорящее

Attempted to read or write protected memory. 
This is often an indication that other memory is corrupt.

из метода Write, где мы записываем коллекцию геометрии в файлы формы.

sfw.Write(FileName, new GeometryCollection(gc.ToArray()));

(GeometryCollection также относится к сторонней dll, GeoAPI.dll)

Эта ошибка приводит к сбою всей службы и делает ее нефункциональной. Затем мы просто перезапустим службу и попытаемся снова запустить те же данные, она будет работать в течение еще одной недели, пока она не рухнет снова. Это происходит только в производстве и в случайные времена. Мы не смогли найти причину проблемы.

Многие форумы предполагают, что это может быть из-за утечек памяти в некотором неуправляемом коде. Но мы не смогли найти его.

Мы также готовы переписать часть, которая создает новые файлы формы. Пожалуйста, помогите мне решить эту проблему. Дайте мне знать, если требуется более подробная информация. Спасибо заранее.

Ответ 1

По моему опыту, это сообщение было результатом утечки памяти. Это то, что я сделал бы, если бы я был в вашей ситуации, особенно потому, что вы работаете с сторонней DLL.

1) Контролируйте свой сервер WCF и посмотрите, что происходит с DLLHost.exe и службами aspnet в диспетчере задач. У меня такое ощущение, что ваша сторонняя DLL имеет утечку памяти, которая заставляет эти 2 службы раздуваться и достигать предела вашей памяти серверов. Именно по этой причине он работает некоторое время, а затем внезапно просто перестает работать.

2) Определите хорошее расписание, когда вы можете перерабатывать память серверов и пул приложений. Поскольку проблема неумолима, вы можете делать это каждую полночь или когда никто не активно ее использует.

3) Напишите хороший код регистрации ошибок, чтобы точно знать, что происходит в течение времени, когда оно увязло. Я бы поставил следующую информацию о журналах ошибок: передаваемые вами параметры, пользователь, столкнувшийся с этой проблемой и т.д. Это значит, что вы точно знаете, что происходит.

4) Проверьте средство просмотра событий, возможно, там есть какая-то информация, которая может определить проблему.

4) После выполнения 1, 2 и 3 и я позвоню вашему стороннему поставщику DLL и посмотрю, что они могут сделать, чтобы помочь вам. Вам может потребоваться предоставить информацию, которую вы собрали из 1, 2, 3 и 4 элементов сверху.

Удачи, и я надеюсь, что это поможет.

Ответ 2

Я думаю, что у вас есть неуправляемый код в третьих библиотеках, которые получают адрес, защищенный системой или используемый другими приложениями.

Ответ 3

У вас есть Access Violation (указатель на память, не принадлежащую вашему прикладному пространству, включая null/mass - 0x0 - address) в одной из ваших сторонних библиотек DLL.

Или иначе это может быть неуправляемый COMObject, который вы используете, что вызывает эту ошибку.

Ответ 4

Случайный характер этой ошибки подскажет мне, что это может быть вопрос нитей. В частности, метод Write ShapefileWriter, возможно, был вызван, получил задержку в потоке, затем вы вызываете Close. Задержанный метод Write затем пытается написать над закрытым (и защищенным) файлом, что может привести к ошибке, которую вы видите.

Это чисто спекуляция, так как нет большого количества кода, чтобы лучше догадаться, но я столкнулся с этой проблемой с использованием библиотек для записи видео, поэтому в вашем случае это может быть одинаково.