Каково преимущество использования COM по плоскости DLL?

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

Это зависит от того, что вы подразумеваете под «навсегда».

Я также слышал, что некоторые JVM действительно возвращают память ОС, когда они готовы и способны. К сожалению, учитывая то, как обычно работают низкоуровневые API памяти, JVM должна отдавать целые сегменты, и, как правило, сложно «эвакуировать» сегмент, чтобы его можно было вернуть.

1117 Но я бы на это не полагался ... потому что есть разные вещи, которые могут помешать возвращению памяти. Скорее всего, JVM не не вернет память операционной системе. Но это не «навсегда» в том смысле, что JVM будет продолжать использовать его. Даже если JVM никогда не достигнет пикового уровня использования, вся эта память поможет повысить эффективность работы сборщика мусора.

В этом случае вы должны убедиться, что ваша максимальная память никогда не бывает слишком высокой, иначе ваше приложение будет постоянно поглощать сотни МБ ОЗУ.

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

(Комментарии ОП ниже указывают, что это не то, что он пытался сказать. Тем не менее, это то, что он сказал.)


Что касается эффективности сбора мусора, мы можем смоделируйте стоимость запуска эффективного сборщика мусора следующим образом:

cost ~= (amount_of_live_data * W1) + (amount_of_garbage * W2)

где W1 и W2 - (мы предполагаем) константы, которые зависят от коллектора. (На самом деле, это чрезмерное упрощение. Первая часть не является линейной функцией от числа живых объектов. Однако я утверждаю, что это не имеет значения для следующего.)

Эффективность коллектора может быть затем сформулирована как:

efficiency = cost / amount_of_garbage_collected

, которая (если мы предположим, что GC собирает все данные) увеличивается до

efficiency ~= (amount_of_live_data * W1) / amount_of_garbage + W2.

Когда GC работает,

heap_size ~= amount_of_live_data + amount_of_garbage

так

efficiency ~= W1 * (amount_of_live_data / (heap_size - amount_of_live_data) )
              + W2.

Другими словами:

  • при увеличении размера кучи эффективность стремится к константе (W2), но
  • вам нужно большое отношение heap_size к amount_of_live_data, чтобы это произошло.

Другой момент заключается в том, что для эффективного копирующего сборщика W2 покрывает только стоимость обнуления пространства, занимаемого мусорными объектами, в «из космоса». Остальное (отслеживание, копирование живых объектов в «космос» и обнуление «из космоса», которое они занимали) является частью первого слагаемого исходного уравнения, т. Е. Покрывается W1. Это означает, что W2, вероятно, быть значительно меньше, чем W1 ... и что первый член окончательного уравнения значим дольше.

Теперь, очевидно, это теоретический анализ, а модель затрат - это упрощение того, как на самом деле сборщики мусора работать (и это не учитывает «реальную» работу, которую выполняет приложение, или эффекты системного уровня, связывающие слишком много памяти.) Однако математика говорит мне, что с точки зрения Эффективность GC , большая куча действительно очень помогает .

6
задан Martin Cote 12 June 2009 в 14:36
поделиться

7 ответов

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

Вы получаете больше возможностей и гибкости (например, наследование от классов, определенных в DLL, что невозможно в COM), но зависимость, таким образом, намного сильнее (необходимо перестроить пользователя для определенные изменения в DLL и т. д.

Часто особенно раздражает то, что все библиотеки DLL и EXE должны использовать один и тот же вид библиотеки времени выполнения и параметров (например, все динамически связаны с неотладочной многопоточной версией msvcrt * например - невозможно перестроить только один, чтобы использовать отладочную версию, без возникновения очень вероятных ошибок!).

Поэтому более слабая связь COM часто предпочтительнее,

5
ответ дан 8 December 2019 в 04:55
поделиться

Все упоминают вещи, которые находятся в столбце плюсов COM. Я упомяну пару недостатков.

  • Когда вы реализуете свою систему с использованием COM, вам необходимо зарегистрировать «серверы» COM (находящиеся в процессе или вне процесса) при установке и отменить их регистрацию при удалении. Это может немного усложнить вашу систему установки и, как правило, требует перезагрузки, если пользователь сначала осторожно не завершит запущенные процессы.

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

  • Согласно правилам COM, после того, как интерфейс был опубликован, его нельзя изменить. Само по себе это не является отрицательным, и вы можете даже возразить, что это заставляет вас тщательно проработать дизайн перед отправкой интерфейса. Но правда в том, что никогда не бывает, и интерфейсы в производственном коде меняются. Несомненно, вам нужно будет либо добавить методы, либо изменить сигнатуры существующих методов. Для этого вам нужно либо нарушить правила COM, что имеет плохие последствия, либо следовать правилам COM, которые более сложны, чем просто добавление параметра к функции, как если бы вы использовали прямую DLL.

8
ответ дан 8 December 2019 в 04:55
поделиться
  • Регистрация и обнаружение
  • Внепроцесс
  • Удаленный вызов

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

1
ответ дан 8 December 2019 в 04:55
поделиться

Если можно избежать, не используйте его. В моем последнем проекте COM привнес много ограничений в использование интерфейсов C ++. Только представьте, что вы не можете просто передать std :: string, а должны использовать массив символов. В этом случае вы создаете строку, а затем копируете ее в массив, который может обрабатываться COM.

Вы также можете использовать только очень ограниченный набор фундаментальных типов, иметь приведение типов и проприетарное управление памятью. Вы не можете использовать new / delete, но должны использовать собственные функции COM.

Вы также не можете просто создать исключение, но должны инициализировать некоторый COM-интерфейс IErrorInfo, который будет повторно запущен на другом конце.

] Так что, если вам это не нужно, не используйте его. Это обязательно испортит ваш дизайн. И если вам это нужно, попробуйте оценить другие возможности взаимодействия: boost :: interprocess, zeroc ice ...

2
ответ дан 8 December 2019 в 04:55
поделиться

COM может быть полезен в простом старом C ++ для:

  • межпроцессного взаимодействия
  • архитектур плагинов
  • сценариев позднего связывания
  • ] «Много, много, больше ...» (tm)

Тем не менее, если вам это не нужно, не используйте его.

6
ответ дан 8 December 2019 в 04:55
поделиться

Интерфейс IUnknown - хороший базовый уровень для поддержки в любом случае - дает вам возможность добавлять функции без нарушения работы старых клиентов (QueryInterface) и повсеместного подсчета ссылок. Вы можете реализовать это, не вкладываясь во все, что есть в COM.

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

Ваша единственная дельта вдали от возможности вызова на другом языке была бы регистрация и фабрика классов.

1
ответ дан 8 December 2019 в 04:55
поделиться

Поскольку интерфейсы не зависят от какой-либо конкретной DLL, на простейшем уровне подход, подобный COM, по крайней мере, освобождает вас от необходимости изменять DLL, обслуживающую интерфейс под капотом, без необходимости перекомпилировать вашу app с новым именем dll.

Использование Full COM с интерфейсами, определенными MIDL, и прокси-заглушками dll означает, что вы можете использовать COM для управления безопасностью потоков в процессе, межпроцессным обменом данными на том же ПК или даже для подключения к объекту COM-сервера на удаленном ПК.

1
ответ дан 8 December 2019 в 04:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: