#c# #.net #unmanaged #unsafe
#c# #.net #неуправляемый #небезопасно
Вопрос:
Я настроил свой проект на прием небезопасного кода и использую следующий вспомогательный класс для определения размера экземпляра:
struct MyStruct
{
public long a;
public long b;
}
public static class CloneHelper
{
public unsafe static void GetSize(BookSetViewModel book)
{
long n = 0;
MyStruct inst;
inst.a = 0;
inst.b = 0;
n = Marshal.SizeOf(inst);
}
}
Это прекрасно работает со структурой. Однако, как только я использую фактический экземпляр класса, который передается в:
public unsafe static void GetSize(BookSetViewModel book)
{
long n = 0;
n = Marshal.SizeOf(book);
}
Я получаю эту ошибку:
Тип ‘BookSetViewModel’ не может быть маршалирован как неуправляемая структура; не может быть вычислен значимый размер или смещение.
Есть идеи, как я мог бы это исправить? Спасибо,
Ответ №1:
Ну, это действительно зависит от того, что вы подразумеваете под «размером» экземпляра. В памяти есть размер отдельного объекта, но обычно вам нужно подумать о любых объектах, на которые ссылается корневой объект. Это то, сколько памяти может быть восстановлено после того, как корневой каталог получит право на сборку мусора… но вы не можете просто добавить их, так как на эти объекты могут ссылаться несколько других объектов, и действительно, могут быть повторяющиеся ссылки даже внутри одного объекта.
В этом сообщении в блоге показан некоторый код, который я использовал ранее для определения размера необработанных объектов (заголовок поля), без учета каких-либо дополнительных затрат из-за объектов, на которые ссылается один объект. Это не то, что я бы использовал в производственном коде, но это полезно для экспериментов с размером объекта при различных обстоятельствах.
Комментарии:
1. Спасибо, Джон. Мне нужно примерно оценить, насколько велика (в байтах) каждая модель BookSetViewModel, и показать ее соответствующим образом на каждой вкладке. Чтобы клиент получил представление о том, насколько велика текущая книга. Я верну этот блог, который вы отправили, и свяжусь с вами. Большое спасибо
2. @Kave: Но почему это представляет интерес для клиента? Если все несколько книг ссылаются на одно и то же очень длинное имя автора (как один строковый объект), следует ли его включать или нет? Кажется очень странным, что клиент интересуется использованием внутренней памяти, если только вы на самом деле не пишете профилировщик.
3. извините, я имел в виду не обычную книгу, а книгу с точки зрения трейдинга. Поэтому каждая книга автоматически уникальна. У нас есть некоторые проблемы с памятью, так как если клиент загружает слишком много книг, память засоряется (все еще WinXP с ограничением памяти 4 ГБ). Поэтому мне нужно отобразить вкладку (на которой находится книга) разными цветами, предупреждая пользователя о том, что было открыто слишком много больших книг, и ему лучше закрыть некоторые. и т.д. Надеюсь, это имеет смысл
4. @Kave: размер самого прямого объекта будет одинаковым для всех объектов — так что, похоже, вас действительно интересуют данные внутри объекта. Я подозреваю, что точная цифра там не будет очень полезной, но если вы выясните, что занимает основную часть данных (например, большие массивы и строки), то это должно дать разумную «приблизительную оценку».
5. Каждая книга имеет несколько вложенных вкладок (макетов). Каждый макет имеет разные столбцы. Но базовые строки одинаковы для каждого макета. Я мог бы также посчитать строки и вычислить их по столбцам, чтобы получить альтернативное измерение…