Re[8]: Смотрел на Java код. ...много думал.
От: CreatorCray  
Дата: 01.11.05 21:14
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Правильно. Там написано почемы ты этого не поймешь пока не познакомился и не перейдешь "на ты" со средством которое хочешь сравнить.

резонно. в таком случае по этой тематике откланиваюсь до поры до времени.

VD>Изумительное замечание.

мда. коряво я там выразился...

VD>А вот тут ты ошибашся. Мы, ну, те что мыслят абстракциями, можем работать с разными задачами. И в зависимости от задачи будетм определять приоритеты.

Задача: портировать код игры под GameCube. Тут абстракции уже не нужны — тут надо брать мануал по девайсу и вдумчиво искать в нем как же впихнуть гигагерцы и гигабайты в мегагерцы и мегабайты. И чтоб скорость при этом не потерять...

CC>>В любом языке с GC мне надо будет теребить этот самый GC ручками чтобы он не ковырял в носу а сразу убивал мусор.

VD>Это очердное заблуждение. Связано оно как раз с тем, что ты не полностью понимашь как работает ЖЦ в современных рантаймах.
AFAIK убиение ненужного происходит не сразу после pointer = NULL; а тогда, когда сработает некая логика в GC...
Если не так — поясни как именно...

VD>Могу только посочувствовать.

Не стоит. Я прекрасно себя чуствую с небезопасным С++ который для решения моих задач подходит как нельзя лучше.

CC>>Кстати никак не получается найти развернутое определение, что же именно включается в этот термин. Не поможете ссылкой?

VD>http://en.wikipedia.org/wiki/Type_safety
VD>http://en.wikipedia.org/wiki/Datatype
Пасиб, но там то же самое что я уже находил. Из сего делаю вывод что я правильно понимал этот термин.

CC>>Верить что лики есть и писать без ликов — все же разные вещи. Разумеется в "любой программе есть ошибки" (с) не помню.

CC>>Но у профи ИМХО таких ляпов как лик быть не должно.

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


VD>А ты вот погляди на ГУИ у ArenaWars. Игра явно не того калибра, что Ку4, а ГУИ на порядки лучше.

Здоровая сильно зараза чтоб из дома тянуть...
Re[7]: Смотрел на Java код. ...много думал.
От: savaDAN  
Дата: 02.11.05 06:46
Оценка:
CC>Брр.. А разве классы только с .нет появились? Дык это я тогда уже оказывается лет 6 (за деньги) на дотнете пишу
CC>И наш теперешний движок тоже на дотнете написан? там жеж классов — море
Стоп! Внимательно читаем мой оригинальный пост, в котором написано что с чем сравнивается. Или что С, что С++ все едино?
Блин, синдром какой-то: если увидел в названии языка букву "С" сразу считаем что это С++ и бросаемся на его защиту
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[9]: Смотрел на Java код. ...много думал.
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.11.05 15:34
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Задача: портировать код игры под GameCube. Тут абстракции уже не нужны — тут надо брать мануал по девайсу и вдумчиво искать в нем как же впихнуть гигагерцы и гигабайты в мегагерцы и мегабайты. И чтоб скорость при этом не потерять...


Согласись это не совсем тоже самое что разработка ПО с нуля. Это именно портирование и оптимизация под конретное железо.

CC>AFAIK убиение ненужного происходит не сразу после pointer = NULL; а тогда, когда сработает некая логика в GC...


Убиения не просходит вообще RTFM (извинясь за грубость).
Логика ЖЦ ищет живые объекты, а не мертвые.

CC>Если не так — поясни как именно...


Это долгая история. Вот тут я уже пытался ответить на этот вопрос:
http://rsdn.ru/forum/?mid=1412468
Автор: VladD2
Дата: 30.09.05

http://rsdn.ru/forum/?mid=1413697
Автор: VladD2
Дата: 03.10.05


VD>>Могу только посочувствовать.

CC>Не стоит. Я прекрасно себя чуствую с небезопасным С++ который для решения моих задач подходит как нельзя лучше.

Я тоже так думал.
Почитай мои сообщения до 2002 года.

CC>>>Кстати никак не получается найти развернутое определение, что же именно включается в этот термин. Не поможете ссылкой?

VD>>http://en.wikipedia.org/wiki/Type_safety
VD>>http://en.wikipedia.org/wiki/Datatype
CC>Пасиб, но там то же самое что я уже находил. Из сего делаю вывод что я правильно понимал этот термин.

Тогда странно что ты не понимшь, как типобезопасность уменьшает лики и исключает UB.

VD>>А ты вот погляди на ГУИ у ArenaWars. Игра явно не того калибра, что Ку4, а ГУИ на порядки лучше.

CC>Здоровая сильно зараза чтоб из дома тянуть...

Стяни с работы.

Естати, о Ку4 жрет 700 метров (из гига). Вылетела пару раз. Хотя конечно красиво.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Смотрел на Java код. ...много думал.
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.11.05 17:08
Оценка: 1 (1) +1
Здравствуйте, eao197, Вы писали:

E>Во-вторых, я наблюдал, как освободившиеся от необходимости контроля памяти программисты успешно забывали освобождать другие ресурсы. В частности, конекшены к БД.


А ты уверен, что они до этого их освобождали?

E> Поиском чего полностью занимали свое освободившееся время. Просто за счет того, что вместе с контролем за памятью у них отобрали идиому RAII.


Это сказка. Никакой RAII не спосает от ручного контроля памяти. Это огромный груз. А вот какраз конроль реусурсов ОС при наличии IDispose и using проблем не вызывает. Тот же RAII вид сбоку.

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

Ладно. Еще раз. В кратце.

Итак, ресусты можно разделить на 3 типа:
1. Общего доступа. При их занятии блокируется тот или иной ресурс и их лики приводят к неверному фукнционированию программы. Пример такого ресурса файл открываемый для четения или записи.
2. Приватные ресурсы. Их потеря не критична. По крйней мере в современых ОС вроде потомков NT или *никсов. К тамим ресурсам относятся большинство ресурсов вроде хэндлов картинок, ГДИ-ресурсов, соеденений с БД и т.п. Проблемы могут возникнуть только при сильном перерасходвании таких ресуросов.
3. Память в языках без ЖЦ. Это самый частый случай в программировании. Средняя программа оперирует еденицами ресурсов ОС, и тысячами, а то и миллионами блоками памяти.

В С++ все эти 3 типа ресурсов обычно не различаются. Это все "ресурсы" и управление ими производится по общей схеме.

В управляемых средах все несколько иначе. Ресусы треьего класса ресурсами не являются, по понятным причинам. Так что управление ресурсами сводится к контролю очень небольшого числа ресусров ОС.

Ресусры из п. 2 хотя и желательно контролировать вручную, но можно и оставить на откуп финализатору ЖЦ. Для этого нужно всего лишь написать финализатор (синтаксис как у деструктора в С++). Если объект хранящий ресус временный (а именно так случается в 99% случаев), то он будет подобнан сборщиком мусора нулевого поколение, азначит проживет не многим дольше процедуры в которой он был занят. Так что потеря ресурсов этого класса может привести только к очень незначительному повышению требований к памяти или ресурсам. Те же драйверы БД могут при нехватке соеденений просто инициировать сборку мусора.

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

Прибавим сюда using с IDispose-ом и вспомним, о том, что RAII автоматически в программах не появляется. fopen\CreateFile ведь никто не отменял. Да и есть множество того же ВыньАПИ не имеющего готовых оберток. Так что не грамотный программист может забыть закрыть файл и там, и там.

Что же мы получаем? В управляемых языках мы получаем практически полное отсуствие необходимости контролировать 99% ресурсов программы, так как это память которой управляет ЖЦ, и имеем средства для контроля ресусрсов ОС. При этом только незначительный процент ресурсов действительно критичен для приложения и то потери ресурсов этого класса обычно легко выявляются.

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

Мой вывод однозначен. Эти притензии высасоны из пальца.

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

E>В-третьих, в языках, где нет явных указателей, а есть только ссылки, есть очень тонкие баги, связанные с копированием ссылки вместо клонирования объекта. На поиски которых так же уходит освободившееся после контроля памяти время.


Да? И что же ты говоришь что на Руби у тебя ошибок меньше?
Это сказка вызванная тем что очень хочется найти проблему там где ее нет.

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

Правда еще и втом, что конкретно C# специально проектировался так чтобы уменьшить количество мест где вообще можно допустить ошибку. Так что не нужно придумывать.

E>Да и про то, что не нужные ссылки необходимо занулять, так же часто забывают.


Это еще одна сказка. Интересно откуда они вообще берутся?
1. Объекты обычно выстраиваются в деревья и умирают целыми группами.
2. В одтнете при записи без отладчика JIT строит таблицу достижимости так, что если объект больше не испльзуется, то ссылка считается недействительной (хотя переменная можеть быть еще видна в области видимости).

E>Так что, имхо, сменили шило на мыло


Ты придумал себе мифы которыми пыташся убедить себя в чем то.

Не нужно рассказывать сказки. Скажи честно что тебе просто хочется чтобы то чем ты не занимашся имело какие-то недостатки.

В общем, ну нежно придумывать. Попробуй и все миф пройдут сами собой.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Смотрел на Java код. ...много думал.
От: CreatorCray  
Дата: 02.11.05 19:07
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Согласись это не совсем тоже самое что разработка ПО с нуля. Это именно портирование и оптимизация под конретное железо.

Соглашусь пожалуй. пример я выбрал не самый удачный

CC>>AFAIK убиение ненужного происходит не сразу после pointer = NULL; а тогда, когда сработает некая логика в GC...

VD>Убиения не просходит вообще RTFM (извинясь за грубость).
VD>Логика ЖЦ ищет живые объекты, а не мертвые.
ну, я так "образно" выразился про освобождение выделенной памяти.

VD>Это долгая история. Вот тут я уже пытался ответить на этот вопрос:

Ок, почитаю на досуге

CC>>Пасиб, но там то же самое что я уже находил. Из сего делаю вывод что я правильно понимал этот термин.

VD>Тогда странно что ты не понимшь, как типобезопасность уменьшает лики и исключает UB.
Ну, я еще согласен что с ней проще искать собственные ашипки и очепятки. Но панацеей это не является и я вижу больше неудобств чем преимуществ. Вижу есессно для себя.
Ладно, наверное хватит копья ломать...

VD>Стяни с работы.

если не забуду опять

VD>Естати, о Ку4 жрет 700 метров (из гига). Вылетела пару раз. Хотя конечно красиво.

Я дома играл на 512-ти... Не фонтан конечно... Но не вылетала покуда ни разу.
Re[8]: Смотрел на Java код. ...много думал.
От: CreatorCray  
Дата: 02.11.05 19:07
Оценка:
Здравствуйте, savaDAN, Вы писали:

CC>>Брр.. А разве классы только с .нет появились? Дык это я тогда уже оказывается лет 6 (за деньги) на дотнете пишу

CC>>И наш теперешний движок тоже на дотнете написан? там жеж классов — море
DAN>Стоп! Внимательно читаем мой оригинальный пост, в котором написано что с чем сравнивается. Или что С, что С++ все едино?
DAN>Блин, синдром какой-то: если увидел в названии языка букву "С" сразу считаем что это С++ и бросаемся на его защиту
Тьфу блин. Что то я про .нет в последнее время много спорил — вот и клемануло что речь про .нет
сорри
Re[11]: Смотрел на Java код. ...много думал.
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.11.05 00:50
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Ну, я еще согласен что с ней проще искать собственные ашипки и очепятки. Но панацеей это не является


А панацей нет в принципе. В природе нет.

CC>и я вижу больше неудобств чем преимуществ.


Это с непривычки. Когда появились Фортран, С и Паскаль народ долгое время упиравшися в работу максимум на уровне ассемблеров, а в основном машинных кодов, тоже не весь сразу оценил приемущество языков высокого уровня. По началу тоже не видили приемуществ. Точнее считали что недостатки (тормоза ведь какие?!) перевешивали.

Я вот тоже после плюсов долго не искал как память реинерпретировать. Потом понял, что это во мне дурные манеры играют. И понял, что можно жить без реинтерпретации памяти. Оказалось, что это очень даже весело и удобно.

CC> Вижу есессно для себя.

CC>Ладно, наверное хватит копья ломать...

Ага.

VD>>Естати, о Ку4 жрет 700 метров (из гига). Вылетела пару раз. Хотя конечно красиво.

CC>Я дома играл на 512-ти... Не фонтан конечно... Но не вылетала покуда ни разу.

Ну, я его до конца прошел. Если сидеть много часов подряд, то вылетает зараза.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Смотрел на Java код. ...много думал.
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.11.05 07:20
Оценка: +1
Здравствуйте, VladD2

Давай сначала определим позиции. Я не считаю сборку мусора злом. Это действительно удобно, если не считать того, что GC может запуститься когда ему заблогорассудится.

Не нравится мне другое. В языках типа Java, Python и Ruby мне дали сборку мусора, но рабрали у меня RAII. В результате, если мне нужно закрыть какой-то ресурс, то я должен вручную вызывать close. Если же в моем коде возможно исключение, то я должен еще и перестраховываться и вызывать close либо в catch, либо в finally. Что не удобно, черевато ошибками и тяжело отлаживается.

Добавленный в C# unsing уже упрощает работу с ресурсами. Но это не RAII. Нормально сделан RAII в сочетании со сборкой мусора в языке D. Да только D пока в таком состоянии, что очень стремно на нем проекты делать.

E>>Во-вторых, я наблюдал, как освободившиеся от необходимости контроля памяти программисты успешно забывали освобождать другие ресурсы. В частности, конекшены к БД.


VD>А ты уверен, что они до этого их освобождали?


Уверен. Нормальна C++ библиотека закрывает все ресурсы в деструкторах. Возьми, например, обычный std::ifstream или std::ofstream. Или библиотеку OTL. Деструкторы чистят за собой все ресурсы.

Есть, конечно и "не нормальные" C++ библиотеки, которые RAII не используют. Тот же ACE, например, во многих классах RAII не предоставляет. Но, во-первых, никто не заставляет тебя использовать эти библиотеки. А, во-вторых, отказ от RAII в C++ вызван или неграмотностью разработчиков (и от их продуктов лучше держаться подальше), либо архитектурными решениями, которые предлагают адекватную замену RAII. Например, в той же ACE вместо автоматического закрытия хендлов в деструкторах предлагается использовать паттерны Reactor, Event_Handler и обработчик handle_close. Для приложений, на которые расчитана ACE, это даже удобнее.

E>> Поиском чего полностью занимали свое освободившееся время. Просто за счет того, что вместе с контролем за памятью у них отобрали идиому RAII.


VD>Это сказка. Никакой RAII не спосает от ручного контроля памяти.


Не нужно мне сказки расказывать. Это ты студентам можешь подобные голословные утверждения делать.
Я уже очень давно для управления памятью RAII механизмы использую (всякие auto_ptr, smart_ref и пр). Утечки памяти у меня -- это боОольшая редкость. Но ты, конечно же, можешь не верить.

В качестве примера еще можно библиотеку Qt привести. Там большинство объектов через new создается. А вызов delete -- крайне редкая операция. И никаких проблем нет, потому что работа с памятью продумана: все объекты объеденены в иерархии родитель-потомок. И при уничтожении родителя все потомки уничтожаются автоматически.

Даже в C-шном Apache похожая идея используется с memory pool-ами. Разве Apache можно причислить к приложениям с хроническими memory leak-ами?

VD> Это огромный груз. А вот какраз конроль реусурсов ОС при наличии IDispose и using проблем не вызывает. Тот же RAII вид сбоку.


Насколько я понял, usign -- это не совсем RAII. Например, как с помошью using разрешить такую ситуацию:
class Some_Actor
    {
    private :
        //! Указатели на потоки, которые реально будут использоваться.
        std::istream * in_;
        std::ostream * out_;
        //! Потоки, на случай работы с файлами, а не со стандартным вводом/выводом.
        std::ifstream file_in_;
        std::ofstream file_out_;
        
    public :
        Some_Actor()
            // По умолчанию будем работать со стандартным вводом/выводом.
            :    in_( &std::cin )
            ,    out_( &std::cout )
            {}
            
        // Стартовать работу. Если какой-то из указателей не равен 0, то вместо
        // соответствующего потока нужно использовать указанный файл.
        void start( const char * in_file_name, const char * out_file_name )
            {
                if( in_file_name )
                    {
                        file_in_.open( in_file_name );
                        in_ = &file_in_;
                    }
                if( out_file_name )
                    {
                        file_out_.open( out_file_name );
                        out_ = &file_out_;
                    }
                ...
            }
        ...
    };


Все. Дальше мне уже не важно, будут ли объекты Some_Actor создаваться на стеке или в хипе. Или вообще быть статическими объектами. Не важно, какой из них с каким файлом работает. Как только Some_Actor разрушается, все открытые им файлы закрываются. Без малейшего участия с моей стороны.

VD>Итак, ресусты можно разделить на 3 типа:

VD>1. Общего доступа. При их занятии блокируется тот или иной ресурс и их лики приводят к неверному фукнционированию программы. Пример такого ресурса файл открываемый для четения или записи.

Сюда же еще и mutex-ы можно добавить. И коннекшены к БД.
Кстати, std::ofstream, открытый для чтения/записи не блокирует файл и позволяет открыть тот же файл для изменения еще раз. Как той же программе, так и любой другой.

VD>2. Приватные ресурсы. Их потеря не критична. По крйней мере в современых ОС вроде потомков NT или *никсов. К тамим ресурсам относятся большинство ресурсов вроде хэндлов картинок, ГДИ-ресурсов, соеденений с БД и т.п. Проблемы могут возникнуть только при сильном перерасходвании таких ресуросов.


Ну ты крут. Т.е., если в приложении есть небольшая утечка ресурсов, то это не баг -- это фича
Я как-то в pcre++ баг нашел с утечкой памяти. Всего одна операция за собой результаты матчинга regexp-а не удаляла. Да и результаты те были -- мелочь пузатая, что-то около 100 байт. После месяца работы сервера, в котором эта операция использовалась, расход памяти шел уже на сотни мегабайт. Операция эта вызывалась слишком часто.

VD>3. Память в языках без ЖЦ. Это самый частый случай в программировании. Средняя программа оперирует еденицами ресурсов ОС, и тысячами, а то и миллионами блоками памяти.


Давай для объективности скажем, что в языках без ЖЦ огромное количество объектов создается на стеке и автоматически разрушается при выходе из области видимости. Работа с такими объектами вообще никаких проблем не вызывает.

VD>В С++ все эти 3 типа ресурсов обычно не различаются. Это все "ресурсы" и управление ими производится по общей схеме.


Что есть благо.

VD>В управляемых средах все несколько иначе. Ресусы треьего класса ресурсами не являются, по понятным причинам. Так что управление ресурсами сводится к контролю очень небольшого числа ресусров ОС.


И не забывать обнулять ссылки на дочерние объекты в вершинах иерархий.

VD>Ресусры из п. 2 хотя и желательно контролировать вручную, но можно и оставить на откуп финализатору ЖЦ. Для этого нужно всего лишь написать финализатор (синтаксис как у деструктора в С++). Если объект хранящий ресус временный (а именно так случается в 99% случаев), то он будет подобнан сборщиком мусора нулевого поколение, азначит проживет не многим дольше процедуры в которой он был занят. Так что потеря ресурсов этого класса может привести только к очень незначительному повышению требований к памяти или ресурсам. Те же драйверы БД могут при нехватке соеденений просто инициировать сборку мусора.


В Java раньше очень настоятельно не рекомендовали использовать финализаторы для освобождения подобных ресурсов. В Ruby финализаторы вообще нигде не упоминаются (хотя я не знаю, может они и есть).

А твой пример с драйвером БД, который инициирует сборку мусора при нехватке коннекшенов -- это сильно. Представим себе: многопоточное приложение с багом по освобождению коннекшена. Какие-то потоки генерят тысячи объектов. Один поток исчерпывает ресурсы и при очередном connection запускается GC. Все приложение замирает. И так периодически. Но наиболее часто в момент пиковой нагрузки, когда коннекшены запрашиваются с большой скоростью. Веселуха, короче.

VD>Прибавим сюда using с IDispose-ом и вспомним, о том, что RAII автоматически в программах не появляется.


Берешь ОО библиотеку и получаешь RAII автоматически и часто бесплатно.

VD> fopen\CreateFile ведь никто не отменял.


Уже давно отменили. Потоками ввода-вывода, например.

VD> Да и есть множество того же ВыньАПИ не имеющего готовых оберток. Так что не грамотный программист может забыть закрыть файл и там, и там.


Это проблемы тех, кто использует ВыньАПИ вместо Qt, FOX или wxWidgets.

Даже если приходится обращаться к специфическим особенностям OC (которые везде, а не только в Windows, не инкапсулированы в ОО библиотеки) проще потратить пару часов на написание обертки вокруг native-вызовов, чем потом тратить дни и недели на отладку. Те, кто в C++ этим не пользовался уже давно ушли в сторону Java, а сейчас пойдут еще и в сторону C#.

VD>Что же мы получаем? В управляемых языках мы получаем практически полное отсуствие необходимости контролировать 99% ресурсов программы, так как это память которой управляет ЖЦ, и имеем средства для контроля ресусрсов ОС. При этом только незначительный процент ресурсов действительно критичен для приложения и то потери ресурсов этого класса обычно легко выявляются.


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


VD>Мой вывод однозначен. Эти притензии высасоны из пальца.


Ну что же, у нас свобода сновидений. Ты можешь верить во что угодно.

VD>Я согласен, что было бы не плохо иметь и автоматическое управление памтью, и автоматическое управление ресурсами. Но если выбирать из того что есть сегодны я не задумываясь выберу ЖЦ и юсинг.


А я бы выбрал GC и RAII. Жалко, что это есть, AFAIK, только в D.

E>>В-третьих, в языках, где нет явных указателей, а есть только ссылки, есть очень тонкие баги, связанные с копированием ссылки вместо клонирования объекта. На поиски которых так же уходит освободившееся после контроля памяти время.


VD>Да? И что же ты говоришь что на Руби у тебя ошибок меньше?


Вот что-то я не помню, где бы я такое говорил. Я говорил, что на Ruby у меня код меньше получается. Это есть.

По статистике, когда-то приведенной Gaperton-ом, количество ошибок на одинаковый объем строк является постоянной величиной и не зависит от языка программирования. Поэтому уменьшение объема кода косвенно приводит к уменьшению количества ошибок.

А вот о том, что при сокрашении объема кода серьезность остающихся в коде ошибок уменьшается -- об этом речи не было. Как раз проблема с копированием ссылки, а не клонированием объекта -- это очень серьезная ошибка (аналога которой в C++ так сразу и не вспомнишь). Я на днях потратил полчаса на то, чтобы понять, почему у меня чужая информация в мой Hash попадает. Оказалось потому, что я не сделал копирование Hash-а, а скопировал ссылку на него. И в Java, в свое время, я на такие грабли наступал. А вот в C++ такой ошибки бы в принципе не было.

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


А откуда берутся ошибки типизации? От грязных хаков, которые тянутся из C и которые тем же WinAPI стимулируются. Переход на нормальный C++ (с шаблонами, ссылками, dynamic_cast-ами) и ОО библиотеки сильно упрощает жизнь.

VD> и управления памятью добавить еще и их, то количество ошибок увеличится.


VD>Правда еще и втом, что конкретно C# специально проектировался так чтобы уменьшить количество мест где вообще можно допустить ошибку. Так что не нужно придумывать.


Правда еще и в том, что языками с GC является не только C#. Есть еще более мейнстримовая Java. Есть еще динамические языки. Когда я говорил о проблемах в языках со сборкой мусора, я говорил о собирательном образе. Ты же все к C# приводишь.

Если C# удобнее других языков с GC, то слава богу. Значит развитие идет в правильном направлении. Только мне кажется, что в области управления ресурсами D ушел еще дальше.

E>>Да и про то, что не нужные ссылки необходимо занулять, так же часто забывают.


VD>Это еще одна сказка. Интересно откуда они вообще берутся?


На alphaworks.ibm.com, кажется, была статья "Memory Leaks in Java" -- там хорошо основные причины излагались.

VD>1. Объекты обычно выстраиваются в деревья и умирают целыми группами.


Или не умирают, если вершина дерева остается живой.

E>>Так что, имхо, сменили шило на мыло


VD>Ты придумал себе мифы которыми пыташся убедить себя в чем то.


Ничуть не бывало. Я рассказал только то, с чем сам в Java столкнулся.

VD>В общем, ну нежно придумывать. Попробуй и все миф пройдут сами собой.


Пробую сейчас с Ruby. RAII не хватает, хотя там и можно применять приемы a-la C#-вский using.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: Смотрел на Java код. ...много думал.
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.11.05 11:19
Оценка: 28 (5)
Здравствуйте, VladD2, Вы писали:

Кстати, о птичках. Управление неуправляемыми ресурсами из управляемого кода — та еще песня
Особенно это касается взаимодействия нескольких Disposable-объектов.
Пример номер 1:
Мы создаем объект StreamReader. В него передаем, соответственно, объект Stream.
При этом закрывать стрим до закрытия ридера нехорошо.
Поэтому интуитивно хочется написать вот такой код:
using(Stream myStream = new FileInfo("...").OpenRead())
{
  using (StreamReader sr = new StreamReader(myStream)
    {
      ...
    }
}

Все хорошо, кроме случая, когда мы отдаем ридер куда-то наружу. Тут уже юзингом не обойдешься. К счастью, Dispose в StreamReader реализован корректно — он сам закрывает стрим. Поэтому работает и вот такой код:
using(TextReader tr = GetReader())
{
  ...
} // здесь будет закрыт и поток. 

private TextReader GetReader()
{
  return new StreamReader(new FileStream("..."));
}

Полное счастье и все такое.
Но! Есть и другие примеры. Вот, в частности, популярный класс System.Drawing.Image. Он оборудован методом загрузки из потока (Image.FromStream(Stream)). Что характерно, поток тоже нельзя закрывать в течение времени жизни картинки (неожиданно, правда? хотя, если подумать, то все логично — зачем читать всю картинку: вдруг понадобится только заголовок). Как же быть? Ура, Image тоже реализует Disposable, и можем ождать, что все будет своевременно закрыто. Увы, не тут то было. Как минимум в FW 2.0 RC, диспоз имаджа не приводит к отпусканию потока. Что помогает возникновению трудноуловимых глюков. А я-то удивлялся, почему в сэмплах МС сначала грузит файл в MemoryStream, и грузит картинку уже из него:
using (Image img = GetImage())
{
...
} // Упс! Файл еще заблокирован!

private Image GetImage()
{
  return Image.FromStream(new FileStream("myimg.gif"));
}

// Вот как приходится делать:
private Image SafeGetImage()
{
  using(Stream imgStream = new FileStream("myimg.gif"))
    {
      byte[] buf = new byte[imgStream.Length];
        imgStream.Read(buf, 0, buf.Length);
        return Image.FromStream(new MemoryStream(buf));
    }
}


В чем мораль? А в том, что для пользования IDisposable — просто гениальная находка. А вот его корректная реализация не всякой мелкой корпорации по зубам. Особенно в условиях передачи владения.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: Смотрел на Java код. ...много думал.
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.11.05 18:00
Оценка:
Здравствуйте, eao197, Вы писали:

E>Добавленный в C# unsing уже упрощает работу с ресурсами. Но это не RAII. Нормально сделан RAII в сочетании со сборкой мусора в языке D. Да только D пока в таком состоянии, что очень стремно на нем проекты делать.


Мне вот интересно. Может все же поиписать на том самом C#, а потом уже выражать мнение о необходимости.

Пойми, в начале знакомства с Шарпом я тоже выражал сожаление о том, что в языке нет деструкторов. Слово RAII мне не было знакомо, но не суть.

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

Ну, и что? А все просто. Прошло время. Я понял почему это не сделно. И понял, что по большому счету это моя фобия, так как в сочетании с принятыми в дотнете правилами работы с ресурсами проблем с контролем ресурсов просто не наблюдается.

Проблема введения деструкторов в язык с вязана с тонкостями работы дотнета. В отличии от С++ в дотнете было принято решение избавиться от такой штуки как копирубщие конструкторы и деструкторы. Точнее не превносить их в архитектуру. Сделано это было для того, чтобы любой объект можно было бы копировать скажем так memmove-ом, т.е. побайтно. За одно это резко урощает реализацию массивов и т.п. и делает семантику массивов вэлью-типов очень близкой к семантике ссылочных массивов.

Все это повзволяет с одной стороны реализовать эффективную автоматику в управлении памяти, а с другой сделать язки вроде Шарпа максимально простыми и понятными.

Расчет же был совсем простым. После того как память исключается из списка ресусрсов которые нужно контролировать программисту, количество ресурсов получается смехотворно малым. Их ничего не стоит проконтролировать вручную. Юсинг снимает послений аргумент лени.

Далее для контроля ресурсов применяется довольно простой набор првил. Он позволяет в большинстве случаев вообще избавиться от контроля. В результате даже совсем не опытный программист может писать программы на Шарпе и не испытывать никаких проблем в контроле ресурсов.

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

VD>>А ты уверен, что они до этого их освобождали?


E>Уверен. Нормальна C++ библиотека закрывает все ресурсы в деструкторах.


Да? А С или АПИ? А если объект из нормальной С++-библиотеки создан через new или того хуже через malloc?

E> Возьми, например, обычный std::ifstream или std::ofstream. Или библиотеку OTL. Деструкторы чистят за собой все ресурсы.


Видимо их там море. Один файловый хэндл. Кстати, в управляемых ОС это тоже будет управляемым ресурсом (ну, да это так отступление).
Незаметить не закрытый хэндл ты не сможешь. Да и файлов обычно открывается очень не много. В итоге промазать с закрытием файла ну, очень не просто.

E>Есть, конечно и "не нормальные" C++ библиотеки, которые RAII не используют. Тот же ACE, например, во многих классах RAII не предоставляет. Но, во-первых, никто не заставляет тебя использовать эти библиотеки.


Хм. Но они есть. То же ВыньАПИ...
Вот тебе пример:
http://rsdn.ru/article/wtl/wtlprint.xml
Автор(ы): Алексей Ширшов
Дата: 09.11.2003
Печать в WTL не так хорошо развита и проработана, как в других библиотеках. Статья рассказывает, как преодолеть недостатки этой библиотеки, используя ее гибкость и открытую структуру.

того как серьезного программиста я так и не смог убедить создать оберкти и не управлять памятью вручную. Смог только отговорить от испольования goto для очистки ресурвов.

E> А, во-вторых, отказ от RAII в C++ вызван или неграмотностью разработчиков (и от их продуктов лучше держаться подальше), либо архитектурными решениями, которые предлагают адекватную замену RAII.


Ну, вот юсинг как раз адекватная замета.

E> Например, в той же ACE вместо автоматического закрытия хендлов в деструкторах предлагается использовать паттерны Reactor, Event_Handler и обработчик handle_close. Для приложений, на которые расчитана ACE, это даже удобнее.


А в дотнете большинство библиотек вообще не требует думать о файлах. Ну, и?

E>>> Поиском чего полностью занимали свое освободившееся время. Просто за счет того, что вместе с контролем за памятью у них отобрали идиому RAII.


VD>>Это сказка. Никакой RAII не спосает от ручного контроля памяти.


E>Не нужно мне сказки расказывать. Это ты студентам можешь подобные голословные утверждения делать.


Это ты их мне рассказывашь.

E>Я уже очень давно для управления памятью RAII механизмы использую (всякие auto_ptr, smart_ref и пр). Утечки памяти у меня -- это боОольшая редкость. Но ты, конечно же, можешь не верить.


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

E>В качестве примера еще можно библиотеку Qt привести. Там большинство объектов через new создается. А вызов delete -- крайне редкая операция. И никаких проблем нет,


Редкая? Значит есть...

E>потому что работа с памятью продумана: все объекты объеденены в иерархии родитель-потомок. И при уничтожении родителя все потомки уничтожаются автоматически.


И сколько времени было затрачено на создание этой стратегии, а потом на отслеживание следование ей?

А сколько случаев не вписались в идею дерева, и потребовали ручной обработки?

E>Даже в C-шном Apache похожая идея используется с memory pool-ами. Разве Apache можно причислить к приложениям с хроническими memory leak-ами?


А вот в Апиче люди попытались создать свой ЖЦ для локальной задачи. Это как раз разуное решение. Жаль не универсальное и слежение за его соблюдением опять таки лежит на программисте.

E>Насколько я понял, usign -- это не совсем RAII. Например, как с помошью using разрешить такую ситуацию:

E>
E>class Some_Actor
E>    {
E>    private :
E>        //! Указатели на потоки, которые реально будут использоваться.
E>        std::istream * in_;
E>        std::ostream * out_;
E>        //! Потоки, на случай работы с файлами, а не со стандартным вводом/выводом.
E>        std::ifstream file_in_;
E>        std::ofstream file_out_;
        
E>    public :
E>        Some_Actor()
E>            // По умолчанию будем работать со стандартным вводом/выводом.
E>            :    in_( &std::cin )
E>            ,    out_( &std::cout )
E>            {}
            
E>        // Стартовать работу. Если какой-то из указателей не равен 0, то вместо
E>        // соответствующего потока нужно использовать указанный файл.
E>        void start( const char * in_file_name, const char * out_file_name )
E>            {
E>                if( in_file_name )
E>                    {
E>                        file_in_.open( in_file_name );
E>                        in_ = &file_in_;
E>                    }
E>                if( out_file_name )
E>                    {
E>                        file_out_.open( out_file_name );
E>                        out_ = &file_out_;
E>                    }
E>                ...
E>            }
E>        ...
E>    };
E>


Дело в том, что так просто стараются не писать. А если пишут, то делают общий IDisposeble в Dispose которого освобождают ссылки.

А посутпают обычно так:
1. Читают все данные в рамках start и хранят тольк результат. А то и вооще ничего не хранят.
2. Организуется пул ресурсов и для отдельных операций используются временные ресурсы которые можно освобождать или юсингом или оставить на отуп ЖЦ.
3. Делается итератор в котором все прозрачно. Юсинг в итераторе автоматом приводит к реализации освобождения ресурсов в Dispose-е итератора.

Другими словами просто не занимаются такой фигней как явным хранением ссылок на ресурсы. Это вообще полезно, так как позволяет блокировать ресурсы на минимальное время.

VD>>Итак, ресусты можно разделить на 3 типа:

VD>>1. Общего доступа. При их занятии блокируется тот или иной ресурс и их лики приводят к неверному фукнционированию программы. Пример такого ресурса файл открываемый для четения или записи.

E>Сюда же еще и mutex-ы можно добавить.


Отнюдь. Мютексы реализованы внутри платформы и в Шарпе для них есть отдельный синтаксис lock(имяОбъекта). Он принципиально распространяется на область видимости, так что считай что исползуется твой любимый RAII.

E> И коннекшены к БД.


Вовсе нет. Подключение к БД не критичный ресурс. Это ресурс из п. 2. К тому же в дотнете подключения управляются пулами. Это позволяет запрашивать их при каждом обращении к БД и контролировать юсингами или просто бросать на произвол ЖЦ.

E>Кстати, std::ofstream, открытый для чтения/записи не блокирует файл и позволяет открыть тот же файл для изменения еще раз. Как той же программе, так и любой другой.


Вот это как раз и есть п. 1. И ошибки с ним ловятся на раз. Файл ведь заблокирован.

VD>>2. Приватные ресурсы. Их потеря не критична. По крйней мере в современых ОС вроде потомков NT или *никсов. К тамим ресурсам относятся большинство ресурсов вроде хэндлов картинок, ГДИ-ресурсов, соеденений с БД и т.п. Проблемы могут возникнуть только при сильном перерасходвании таких ресуросов.


E>Ну ты крут. Т.е., если в приложении есть небольшая утечка ресурсов, то это не баг -- это фича


Э... Это не С++. Утечки нет. Просто освобождение происходит не по стэку, а с небольшой задержкой. Ну, например, произошла отрисовка и когда процессор освободился происходит сбор нулевого поколения при котором все ресусры и очищаются.

E>Я как-то в pcre++ баг нашел с утечкой памяти. Всего одна операция за собой результаты матчинга regexp-а не удаляла. Да и результаты те были -- мелочь пузатая, что-то около 100 байт. После месяца работы сервера, в котором эта операция использовалась, расход памяти шел уже на сотни мегабайт. Операция эта вызывалась слишком часто.


Не нужно переносить маргинальный опыт плюсов на управляемые среды.
Утечек просто не будет. А память как ты помнишь вообще не рерсурс. Она контролируется автоматом. Все что не занято — свободно.

VD>>3. Память в языках без ЖЦ. Это самый частый случай в программировании. Средняя программа оперирует еденицами ресурсов ОС, и тысячами, а то и миллионами блоками памяти.


E>Давай для объективности скажем, что в языках без ЖЦ огромное количество объектов создается на стеке и автоматически разрушается при выходе из области видимости. Работа с такими объектами вообще никаких проблем не вызывает.


Дык вэлью-типы никто не отменял. Но в ОО-приложении без динамически созданных экземпляров обычно не обходится. В нормальном ОО-приложении количество памяти которую нужно контролировать просто огромно.

VD>>В С++ все эти 3 типа ресурсов обычно не различаются. Это все "ресурсы" и управление ими производится по общей схеме.


E>Что есть благо.


Что есть невероятное зло, так как память является ресурсом который нужно все время контролировать. А это самый огромный ресурс.

VD>>В управляемых средах все несколько иначе. Ресусы треьего класса ресурсами не являются, по понятным причинам. Так что управление ресурсами сводится к контролю очень небольшого числа ресусров ОС.


E>И не забывать обнулять ссылки на дочерние объекты в вершинах иерархий.


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

E>В Java раньше очень настоятельно не рекомендовали использовать финализаторы для освобождения подобных ресурсов. В Ruby финализаторы вообще нигде не упоминаются (хотя я не знаю, может они и есть).


Я рад за них.

E>А твой пример с драйвером БД, который инициирует сборку мусора при нехватке коннекшенов -- это сильно. Представим себе: многопоточное приложение с багом по освобождению коннекшена. Какие-то потоки генерят тысячи объектов. Один поток исчерпывает ресурсы и при очередном connection запускается GC. Все приложение замирает. И так периодически. Но наиболее часто в момент пиковой нагрузки, когда коннекшены запрашиваются с большой скоростью. Веселуха, короче.


Почему замирают? Сборка мусора — это молниеносная операция. К тому же до этого почти никогда не доходит. Это как бы последняя защита от гипотетической проблемы. Соеденения с БД управляется пулом и просто нет необходимости его прикапывать на долго. По этому есди даже не использовать юсинг, оно умирает при первой сборке нулевого поколения. А они в любом нормальном приложении обычно как из пулемета происходят. Нулевое поколение это как бы стэк донета.

VD>>Прибавим сюда using с IDispose-ом и вспомним, о том, что RAII автоматически в программах не появляется.


E>Берешь ОО библиотеку и получаешь RAII автоматически и часто бесплатно.


В программе на С++ очень редко обходится без общения с С-АПИ. А это значит, что мест где прийдется хотя бы прикручивать обертку к вручную управляемому ресурсу более чем достаточно. Плюс не сегда владение ресурсом можно описать деревом.

Ну, и главное — это геморрой. Ведь политику владения объектом нужно продумывать и отслеживать. А что если циглическая ссылка? Или еще что...

VD>> fopen\CreateFile ведь никто не отменял.


E>Уже давно отменили. Потоками ввода-вывода, например.


Да? Погляди примеры сам знашь кого. Вот это
Автор(ы): Алексей Ширшов
Дата: 09.11.2003
Печать в WTL не так хорошо развита и проработана, как в других библиотеках. Статья рассказывает, как преодолеть недостатки этой библиотеки, используя ее гибкость и открытую структуру.
я тебе тоже показывал.

VD>> Да и есть множество того же ВыньАПИ не имеющего готовых оберток. Так что не грамотный программист может забыть закрыть файл и там, и там.


E>Это проблемы тех, кто использует ВыньАПИ вместо Qt, FOX или wxWidgets.


Qt тоже оберток не имеет. Да и проблемы эти один хрен есть. Что же людям застрелиться если они используют КОМ или КОРБУ?

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

Вот ты тут все пошь: Апач, КуТи, АСЕ... А раскажи мне как будет выглядеть работа с венигретом в котором по некоторой не зависящей от тебя причине попало все это? Прикинь Апач на котором АСЕ, буст, кусти КуТи и т.п. У каждого свои политики владения объектами. Это же повеситься можно в преключении мозгов на их отслеживание!!!

E>Даже если приходится обращаться к специфическим особенностям OC (которые везде, а не только в Windows, не инкапсулированы в ОО библиотеки) проще потратить пару часов на написание обертки вокруг native-вызовов, чем потом тратить дни и недели на отладку.


Согласен, что конечно это самый грамотный выход. Но:
1. Не все так считают.
2. Обертка так же может приводить к утечкам.
3. На их написание нужно убивать время. Порой большее чем на саму задачу решаемую оберткой.
4. Нужно отслеживать политики владения чтобы не получить проблем второго и более порядков. Ох никак не забуду ловлю багов вылезавших в релизе КОМ-овского приожения где были пара синглтонов и 8 модулей.

E> Те, кто в C++ этим не пользовался уже давно ушли в сторону Java, а сейчас пойдут еще и в сторону C#.


Ты знашь я как раз в С++ всем этим пользовался. Потому и говрю, что идиотизм все это. Можно жить куда проще и удобнее.

У меня в конторе было правило — никаких голых хэндлов и указаетелй. Вот это дело: http://rsdn.ru/article/files/libs/handlelib.xml
Автор(ы): Павел Блудов, Александр Корсуков, Владислав Чистяков
Дата: 09.06.2004
Библиотека классов-оберток для объектов ядра windows.
родилось как раз в следствии этого правила, так как задолбались клепать обертки.

E>Ну что же, у нас свобода сновидений. Ты можешь верить во что угодно.


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

E>А я бы выбрал GC и RAII. Жалко, что это есть, AFAIK, только в D.


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

E>Вот что-то я не помню, где бы я такое говорил. Я говорил, что на Ruby у меня код меньше получается. Это есть.


Ну, а где ты гворил о том, что в Руби есть проблемы с освобождением ресурсов?

E>По статистике, когда-то приведенной Gaperton-ом, количество ошибок на одинаковый объем строк является постоянной величиной и не зависит от языка программирования. Поэтому уменьшение объема кода косвенно приводит к уменьшению количества ошибок.


Ну, эта теория слишком сомнительна. Это он ФЯ выгораживал. А вообще без управления памятью и кода будет меньше.

E>А вот о том, что при сокрашении объема кода серьезность остающихся в коде ошибок уменьшается -- об этом речи не было. Как раз проблема с копированием ссылки, а не клонированием объекта -- это очень серьезная ошибка (аналога которой в C++ так сразу и не вспомнишь).


Можно ссылки с жалобами на это дело?

E> Я на днях потратил полчаса на то, чтобы понять, почему у меня чужая информация в мой Hash попадает. Оказалось потому, что я не сделал копирование Hash-а, а скопировал ссылку на него. И в Java, в свое время, я на такие грабли наступал. А вот в C++ такой ошибки бы в принципе не было.


Это как? Где ты его брал?

E>А откуда берутся ошибки типизации?


От невозможности писать весь код в типобезопасном режиме. От желания сделать его по быстрее (ну, там memmove/memset в С++). От необходимости постоянно работать с С-АПИ. Да от многого.

E>От грязных хаков, которые тянутся из C и которые тем же WinAPI стимулируются. Переход на нормальный C++ (с шаблонами, ссылками, dynamic_cast-ами) и ОО библиотеки сильно упрощает жизнь.


Да не очень то перйдешь. И не очень то упрощает. Для этого ведь нормальный рантайм нужен. А его нет. Плюс борьба за скорость...

E>Правда еще и в том, что языками с GC является не только C#. Есть еще более мейнстримовая Java.


Куда ж более то?

E> Есть еще динамические языки. Когда я говорил о проблемах в языках со сборкой мусора, я говорил о собирательном образе. Ты же все к C# приводишь.


А что мне говорить о сферокониках. Есть дотнет и Шарп. Количество ошибок в них несравнимо меньше чем в С++. Тут даже обсуждать нечего. Можно только понты покидать о своей крутости (это я не о тебе, но таких хватает).

VD>>1. Объекты обычно выстраиваются в деревья и умирают целыми группами.


E>Или не умирают, если вершина дерева остается живой.


Примеры в студию.

VD>>В общем, ну нежно придумывать. Попробуй и все миф пройдут сами собой.


E>Пробую сейчас с Ruby. RAII не хватает, хотя там и можно применять приемы a-la C#-вский using.


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

Кстати, Руби явно значительно менее защищенный от ошибок язык. Возможно в этом и дело.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Смотрел на Java код. ...много думал.
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.11.05 22:27
Оценка: +1
Здравствуйте, VladD2, Вы писали:

E>>Уверен. Нормальна C++ библиотека закрывает все ресурсы в деструкторах.


VD>Да? А С или АПИ? А если объект из нормальной С++-библиотеки создан через new или того хуже через malloc?


Через malloc объекты не создают. Даже если хочется разместить объект в заранее выделенном блоке памяти, то std::vector<char>, а затем placement new и все дела.
А если объект создается через new то для него тот же std::auto_ptr есть.

E>>В качестве примера еще можно библиотеку Qt привести. Там большинство объектов через new создается. А вызов delete -- крайне редкая операция. И никаких проблем нет,


VD>Редкая? Значит есть...




E>>потому что работа с памятью продумана: все объекты объеденены в иерархии родитель-потомок. И при уничтожении родителя все потомки уничтожаются автоматически.


VD>И сколько времени было затрачено на создание этой стратегии, а потом на отслеживание следование ей?


Сколько времени затрачено на создание теперь уже не важно. Qt уже лет десять, если не больше. А следовать этой стратегии совсем не сложно. Qt вообще очень легко изучается. Бывшие студенты осваивают ее в лет.

VD>А сколько случаев не вписались в идею дерева, и потребовали ручной обработки?


Не помню вообще такого. Там объекты хоть на стеке создавай, хоть в хипе -- они все равно корректно умирают.

VD>Дело в том, что так просто стараются не писать. А если пишут, то делают общий IDisposeble в Dispose которого освобождают ссылки.


Но ведь пишут. А с деструкторами писать не нужно

VD>А посутпают обычно так:

VD>1. Читают все данные в рамках start и хранят тольк результат. А то и вооще ничего не хранят.

Ну это на тему "память больше не ресурс"

VD>2. Организуется пул ресурсов и для отдельных операций используются временные ресурсы которые можно освобождать или юсингом или оставить на отуп ЖЦ.

VD>3. Делается итератор в котором все прозрачно. Юсинг в итераторе автоматом приводит к реализации освобождения ресурсов в Dispose-е итератора.

VD>Другими словами просто не занимаются такой фигней как явным хранением ссылок на ресурсы. Это вообще полезно, так как позволяет блокировать ресурсы на минимальное время.


Интересные примеры на эту тему Sinclair привел: Re[10]: Смотрел на Java код. ...много думал.
Автор: Sinclair
Дата: 03.11.05


E>> И коннекшены к БД.


VD>Вовсе нет. Подключение к БД не критичный ресурс.


Не знаю. Когда мне приходилось их отслеживать, это был весьма критичный ресурс, причем очень органиченный. Что-то типа 5 или 10 одновременных коннекшенов к БД.

E>>Кстати, std::ofstream, открытый для чтения/записи не блокирует файл и позволяет открыть тот же файл для изменения еще раз. Как той же программе, так и любой другой.


VD>Вот это как раз и есть п. 1. И ошибки с ним ловятся на раз. Файл ведь заблокирован.


Нет, Влад, простой std::ofstream или fopen не блокирует файл. Разве что от переименования. Для блокирования файла при открытии нужно либо CreateFile задействовать, либо sopen (это под Windows). А в Unix-е после открытия файла нужно через fcntl блокировать фрагмент файла.

VD>>>3. Память в языках без ЖЦ. Это самый частый случай в программировании. Средняя программа оперирует еденицами ресурсов ОС, и тысячами, а то и миллионами блоками памяти.


E>>Давай для объективности скажем, что в языках без ЖЦ огромное количество объектов создается на стеке и автоматически разрушается при выходе из области видимости. Работа с такими объектами вообще никаких проблем не вызывает.


VD>Дык вэлью-типы никто не отменял. Но в ОО-приложении без динамически созданных экземпляров обычно не обходится. В нормальном ОО-приложении количество памяти которую нужно контролировать просто огромно.


Обычно не обходится. Но так же обычно все эти операции с хипом очень тчательно от меня скрыты. Например, я много работаю с STL контейнерами (list, vector, deque, set, map) -- и практически всегда передаю туда ссылки на автоматические объекты, а не указатели. А уже контейнеры работают с хипом. Причем очень хорошо работают.

E>>А твой пример с драйвером БД, который инициирует сборку мусора при нехватке коннекшенов -- это сильно. Представим себе: многопоточное приложение с багом по освобождению коннекшена. Какие-то потоки генерят тысячи объектов. Один поток исчерпывает ресурсы и при очередном connection запускается GC. Все приложение замирает. И так периодически. Но наиболее часто в момент пиковой нагрузки, когда коннекшены запрашиваются с большой скоростью. Веселуха, короче.


VD>Почему замирают? Сборка мусора — это молниеносная операция.




VD>Вот ты тут все пошь: Апач, КуТи, АСЕ... А раскажи мне как будет выглядеть работа с венигретом в котором по некоторой не зависящей от тебя причине попало все это? Прикинь Апач на котором АСЕ, буст, кусти КуТи и т.п. У каждого свои политики владения объектами. Это же повеситься можно в преключении мозгов на их отслеживание!!!


К счастью, все эти библиотеки решают разные задачи (за исключением Apache Portable Runtime и ACE, но вряд ли кто-нибудь их в одном проекте сведет, все же APR -- это чисто C-шная либа). Поэтому в случае конкретно с ACE, Boost и Qt проблем я не вижу.

А вообще, ты прав. Объединение в одном C++ разнородных библиотек -- это серьезная задача. В языках с GC все на порядки проще.

E>>Вот что-то я не помню, где бы я такое говорил. Я говорил, что на Ruby у меня код меньше получается. Это есть.


VD>Ну, а где ты гворил о том, что в Руби есть проблемы с освобождением ресурсов?


Да хотя бы здесь:
f = File.new( "myfile.txt" )
f.gets ... # какая-то обработка.
# Упс! Забыли f.close вызвать.


А вот так эта проблема решается с помощью using-похожего механизма:
File.open( "myfile.txt" ) { |f| f.gets ... }

При выходе из блока кода с обработкой содержимого файла, файл автоматически закрывается. На самом деле там нет никаких фокусов c IDisposable, просто этот вариант open раскрывается во что-то подобное:
def File.open(file_name)
    f = File.new(file_name)
    if block_given? # Если передали в функцию блок кода...
        begin # аналог try
            yeild f # вызываем этот блок...
        ensure # аналог finally
            f.close
        end
        return nil
    else
        return f
    end
end


E>> Я на днях потратил полчаса на то, чтобы понять, почему у меня чужая информация в мой Hash попадает. Оказалось потому, что я не сделал копирование Hash-а, а скопировал ссылку на него. И в Java, в свое время, я на такие грабли наступал. А вот в C++ такой ошибки бы в принципе не было.


VD>Это как? Где ты его брал?


А это я строил один Hash, ключем которого была строка, а значением -- еще один Hash с результатами обработки. Затем мне из этого Hash-а часть данных нужно было перекинуть во второй Hash. Ну я так и сделал:
b[ key ] = a[ key ]

Но на самом деле я скопировал ссылку на Hash с результатами обработки, а не его значение. Поэтому, когда я пошел дальше делать обработку b, то оказалось что значения из b как-то появляются в a
А нужно было делать:
b[ key ] = a[ key ].clone


E>>А откуда берутся ошибки типизации?


VD>От желания сделать его по быстрее (ну, там memmove/memset в С++).


За такие вещи руки, вообще-то отрывать нужно

E>>Правда еще и в том, что языками с GC является не только C#. Есть еще более мейнстримовая Java.


VD>Куда ж более то?


Более, более, не сумлевайся
Пока еще более. Хотя по своим фичам C# мне более симпатичен, чем Java. Туда бы еще нормальный code convention...

E>>Или не умирают, если вершина дерева остается живой.


VD>Примеры в студию.


Статьи:
Handling memory leaks in Java programs
Java memory leaks -- Catch me if you can

А вот набор ссылок на эту тему оттуда же: http://www-128.ibm.com/search/searchResults.jsp?searchType=1&amp;searchSite=dW&amp;searchScope=dW&amp;query=Memory%20Leaks%20in%20Java&amp;Search.x=0&amp;Search.y=0

VD>Кстати, Руби явно значительно менее защищенный от ошибок язык. Возможно в этом и дело.


Да я уже давно пришел к мнению, что Ruby совсем не так прост, как кажется. Наверное, и за это так же он мне нравится.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[13]: Смотрел на Java код. ...много думал.
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.11.05 00:26
Оценка:
Здравствуйте, eao197, Вы писали:


E>Через malloc объекты не создают. Даже если хочется разместить объект в заранее выделенном блоке памяти, то std::vector<char>, а затем placement new и все дела.


Еще как создают. Я еще не те извращения видел.

E>А если объект создается через new то для него тот же std::auto_ptr есть.


Который нужно подставлять вручную. И какая разница с юсингом?

E>Сколько времени затрачено на создание теперь уже не важно. Qt уже лет десять, если не больше. А следовать этой стратегии совсем не сложно. Qt вообще очень легко изучается. Бывшие студенты осваивают ее в лет.


На КуТи свет клином не сошелся.

VD>>А сколько случаев не вписались в идею дерева, и потребовали ручной обработки?


E>Не помню вообще такого. Там объекты хоть на стеке создавай, хоть в хипе -- они все равно корректно умирают.


Пока дерево. Первое кольцо и...

VD>>Дело в том, что так просто стараются не писать. А если пишут, то делают общий IDisposeble в Dispose которого освобождают ссылки.


E>Но ведь пишут. А с деструкторами писать не нужно


Не пишут. У ламеров вообрежения на это не хватает, а у остальных хватает ума так не писать.

E>Ну это на тему "память больше не ресурс"


Для многих задач оптимальное решение — это построение модели данных в памяти. Для других пакетная обработка. Так что копья ломать?

E>Интересные примеры на эту тему Sinclair привел: Re[10]: Смотрел на Java код. ...много думал.
Автор: Sinclair
Дата: 03.11.05


Ничего там интересного. Там куча лишних действий которые от избытка энергии разве что можно сделать.

E>Не знаю. Когда мне приходилось их отслеживать, это был весьма критичный ресурс, причем очень органиченный. Что-то типа 5 или 10 одновременных коннекшенов к БД.


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

VD>>Вот это как раз и есть п. 1. И ошибки с ним ловятся на раз. Файл ведь заблокирован.


E>Нет, Влад, простой std::ofstream или fopen не блокирует файл. Разве что от переименования. Для блокирования файла при открытии нужно либо CreateFile задействовать, либо sopen (это под Windows). А в Unix-е после открытия файла нужно через fcntl блокировать фрагмент файла.


Думаю ты ошибаешся. Это как раз для параллельного доступа нужно CreateFile испольовать. К тому же это не важно. Если ресурс не блокируется, то это сразу перестает быть п. 1.

E>Обычно не обходится. Но так же обычно все эти операции с хипом очень тчательно от меня скрыты. Например, я много работаю с STL контейнерами (list, vector, deque, set, map) -- и практически всегда передаю туда ссылки на автоматические объекты, а не указатели. А уже контейнеры работают с хипом. Причем очень хорошо работают.


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

VD>>Почему замирают? Сборка мусора — это молниеносная операция.

E>

А что ты улыбашся. Это факт. Ты просто не интересовался этим вопросом серьезно. Я вот интересовался. Заметить на глаз процесс сборки мусора невозможно на современных процессорах.

E>К счастью, все эти библиотеки решают разные задачи (за исключением Apache Portable Runtime и ACE, но вряд ли кто-нибудь их в одном проекте сведет, все же APR -- это чисто C-шная либа). Поэтому в случае конкретно с ACE, Boost и Qt проблем я не вижу.


А ты почитай о планах создания Януса на С++. Как раз хотели запихнуть почти все это дело в одно приложение.

E>А вообще, ты прав. Объединение в одном C++ разнородных библиотек -- это серьезная задача. В языках с GC все на порядки проще.


Именно. И дело и менно в том, что каждая из них пропагандирует собственную политику владения объектами.

Вообще дотнет в принципе снимает много проблем именно стандартизацией. Там где в С++ приходится или выбирать что-то одно, или мириться с нестандартностью в Шарпе обычно решаетя однообразно да еще и описано в разных стайл-гайдах. В итоге повторное использование кода значительно выше.

E>Да хотя бы здесь:

E>
E>f = File.new( "myfile.txt" )
E>f.gets ... # какая-то обработка.
E># Упс! Забыли f.close вызвать.
E>


А не ты ли говорил, что файл сам закроется при выходе из области видимости?

E>А вот так эта проблема решается с помощью using-похожего механизма:

E>
E>File.open( "myfile.txt" ) { |f| f.gets ... }
E>

E>При выходе из блока кода с обработкой содержимого файла, файл автоматически закрывается. На самом деле там нет никаких фокусов c IDisposable, просто этот вариант open раскрывается во что-то подобное:
E>
E>def File.open(file_name)
E>    f = File.new(file_name)
E>    if block_given? # Если передали в функцию блок кода...
E>        begin # аналог try
E>            yeild f # вызываем этот блок...
E>        ensure # аналог finally
E>            f.close
E>        end
E>        return nil
E>    else
E>        return f
E>    end
E>end
E>


Ну, это далеко не юсинг. Это аналог форича и итераторов внутри которого стоит finally.

E>За такие вещи руки, вообще-то отрывать нужно


Надо, не надо. Но это факт. И в большинстве случаев работает. Вот только с меньшинством траху не оберешся.

E>Пока еще более. Хотя по своим фичам C# мне более симпатичен, чем Java. Туда бы еще нормальный code convention...


Вот ну на фиг ваш наормальный. Мы уже лучше помучиемся с тем что есть.

E>Статьи:

E>Handling memory leaks in Java programs
E>Java memory leaks -- Catch me if you can

Не, ты мне вот покажи на нашем форуме... Ну, должно же быть такое же засилие вопросов как по ликам в С++?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Смотрел на Java код. ...много думал.
От: vladserge Россия  
Дата: 04.11.05 06:09
Оценка:
Здравствуйте, c-smile, Вы писали:


CS>Вот такой вот показательный пример,


CS>Фрагмент (очень неполный) читает нечто по протоколу superset of http


CS>Еще раз ничего личного ни про Java ни про другие фреймворки.

CS>Просто разработка надежного кода занимает ровно то же самое время что с что без.
CS>Глубокое заблуждение что если managed code то типа надежная система автоматом.


в догонку
Автор: vladserge
Дата: 15.09.05
С Уважением Сергей Чикирев
Re[6]: Многия знания - многия печали
От: c-smile Канада http://terrainformatica.com
Дата: 04.11.05 06:53
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Здравствуйте, c-smile, Вы писали:


CS>>Проблема в том что среди десяти threads появляется одна в которой

CS>>выполняется этот вот кусок. И все. Всем привет.
CS>>GC начинает останавливать все потоки. Когда они *все* остановились
CS>>тогда чистится мусор. Затем вся эта бодяга весело перезапускается.
CS>>Тут же выпадая в следующий осадок. Потому как тот IP на котором
CS>>работает приведенный фрагмент сидит на жирной трубе.

A>>>Зачем? Для этого у GC есть поколения.


CS>>Есть поколения и что? Не надо останавливать потоки?

CS>>Такого чуда имхо еще нет. В Java есть но в специфических продуктах.

ANS>afair, в 1.5 есть конкурентные сборщики не только для "молодого" поколения (который "parallel"), но и для tenured (сборщик "concurent"). Он останавливает потоки не на всё время сборки мусора.

ANS>Можно попробовать молодое поколение побольше сделать. Вы какие крутилки у ВМ крутили?

там вообще-то еще MS Java жужжит и кстати нормально так жужжит. Если при проектировании считать память ресурсом то все работает.
Re[14]: Смотрел на Java код. ...много думал.
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.11.05 10:21
Оценка:
Здравствуйте, VladD2, Вы писали:

E>>А если объект создается через new то для него тот же std::auto_ptr есть.


VD>Который нужно подставлять вручную. И какая разница с юсингом?


Тем, что у std::auto_ptr есть методы reset и release, а так же std::auto_ptr передает владение указателем, что бывает очень удобно.

VD>>>Вот это как раз и есть п. 1. И ошибки с ним ловятся на раз. Файл ведь заблокирован.


E>>Нет, Влад, простой std::ofstream или fopen не блокирует файл. Разве что от переименования. Для блокирования файла при открытии нужно либо CreateFile задействовать, либо sopen (это под Windows). А в Unix-е после открытия файла нужно через fcntl блокировать фрагмент файла.


VD>Думаю ты ошибаешся. Это как раз для параллельного доступа нужно CreateFile испольовать. К тому же это не важно. Если ресурс не блокируется, то это сразу перестает быть п. 1.


Нет, я не ошибаюсь, вот пример:
#include <fstream>
#include <iostream>
#include <string>
#include <stdexcept>

void do_test()
    {
        const std::string file_name( "test.txt" );
        const std::string content( "Hello, world!" );

        // Пресоздаем файл для записи.
        std::ofstream out_file( file_name.c_str(), std::ios::out | std::ios::trunc );

        // И открываем его тут же для чтения.
        std::ifstream in_file( file_name.c_str(), std::ios::in );

        // Размер файла, открытого на чтение равен 0.
        in_file.seekg( 0, std::ios::end );
        if( 0 != in_file.tellg() )
            throw std::runtime_error( "EOF in in_file expexted!" );

        // Записываем в выходной файл строку...
        out_file << content << std::flush;

        // И считываем ее в том же виде из входного файла.
        std::string in_line;
        std::getline( in_file, in_line );

        // Должна получиться та же самая строка.
        if( content != in_line )
            throw std::runtime_error( "expected value: " + content +
                    ", actual value: " + in_line );
    }

int main()
    {
        try
            {
                do_test();
            }
        catch( const std::exception & x )
            {
                std::cerr << "Oops! " << x.what() << std::endl;
            }
    }


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

E>>Обычно не обходится. Но так же обычно все эти операции с хипом очень тчательно от меня скрыты. Например, я много работаю с STL контейнерами (list, vector, deque, set, map) -- и практически всегда передаю туда ссылки на автоматические объекты, а не указатели. А уже контейнеры работают с хипом. Причем очень хорошо работают.


VD>Опять же приходим к продумыванию политики владения объектами. В общем, автоматики как не было, так и нет. Есть головная боль.


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

E>>К счастью, все эти библиотеки решают разные задачи (за исключением Apache Portable Runtime и ACE, но вряд ли кто-нибудь их в одном проекте сведет, все же APR -- это чисто C-шная либа). Поэтому в случае конкретно с ACE, Boost и Qt проблем я не вижу.


VD>А ты почитай о планах создания Януса на С++. Как раз хотели запихнуть почти все это дело в одно приложение.


Знаешь, фраза "планы о создания чего-нибудь" у меня вызывает только ироническую улыбку. Лично мой опыт показывает, что планировать можно что угодно и как угодно. А до реализации это в большинстве случаев не доходит. Так же и здесь. Проблема не в том, что слишком много инструментов предлагалось. А в том, что "предлагалось" вместо "использовалось".

E>>А вообще, ты прав. Объединение в одном C++ разнородных библиотек -- это серьезная задача. В языках с GC все на порядки проще.


VD>Именно. И дело и менно в том, что каждая из них пропагандирует собственную политику владения объектами.


+1

Для C++, имхо, это одна из причин того, что нет настолько серьезных фреймворков, как JDK, .NET Framework, Perl CPAN или RubyGems. И, как следствие, понижает шансы C++ в борьбе с более молодыми и централизованно развиваемыми конкурентами.

VD>Вообще дотнет в принципе снимает много проблем именно стандартизацией. Там где в С++ приходится или выбирать что-то одно, или мириться с нестандартностью в Шарпе обычно решаетя однообразно да еще и описано в разных стайл-гайдах. В итоге повторное использование кода значительно выше.


+1
Это не только в Шарпе так. Но и в Java, и в Python, и в Ruby.

E>>Да хотя бы здесь:

E>>
E>>f = File.new( "myfile.txt" )
E>>f.gets ... # какая-то обработка.
E>># Упс! Забыли f.close вызвать.
E>>


VD>А не ты ли говорил, что файл сам закроется при выходе из области видимости?


Не помню такого. Имхо, это был FR в разговоре про Python (где-то в дебрях этой темы: Re[37]: Python vs C#
Автор: FR
Дата: 13.05.05
).

E>>А вот так эта проблема решается с помощью using-похожего механизма:

E>>
E>>File.open( "myfile.txt" ) { |f| f.gets ... }
E>>

E>>При выходе из блока кода с обработкой содержимого файла, файл автоматически закрывается. На самом деле там нет никаких фокусов c IDisposable, просто этот вариант open раскрывается во что-то подобное:
E>>
...
E>>


VD>Ну, это далеко не юсинг. Это аналог форича и итераторов внутри которого стоит finally.


Тем не менее, при использовании это почти тот же самый using.

E>>Статьи:

E>>Handling memory leaks in Java programs
E>>Java memory leaks -- Catch me if you can

VD>Не, ты мне вот покажи на нашем форуме... Ну, должно же быть такое же засилие вопросов как по ликам в С++?


Не, Влад, не утрируй. Я не утверждал, что в Java столько же ликов, сколько в C++. Но вот то, что они бывают, это точно. К тому же я упеваю читать только "Философию программирования" и, изредка, форумы по C++ и Unix. А в форумы по Java вообще не заглядываю.

Ты, кстати, сам как оцениваешь популярность Java-вского форума на Rsdn? Судя по количеству приверженцев Java в "Философии программирования" на Rsdn их относительно не много (по сравнению с C++ и .Net).
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[14]: Смотрел на Java код. ...много думал.
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.11.05 06:17
Оценка: 1 (1) +1
Здравствуйте, VladD2, Вы писали:

E>>Интересные примеры на эту тему Sinclair привел: Re[10]: Смотрел на Java код. ...много думал.
Автор: Sinclair
Дата: 03.11.05


VD>Ничего там интересного. Там куча лишних действий которые от избытка энергии разве что можно сделать.

А, ну то есть то, что орлы в MS не смогли корректно реализовать IDisposable — это от избытка энергии? А я-то дурак думал, это от того, что понять, когда вызывать Dispose на мембере, не всегда так легко, как хотелось. Я тебе еще десяток могу примеров привести, но они, в отличие от System.Drawing.Image, будут вымышленными.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: Смотрел на Java код. ...много думал.
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.11.05 13:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>А, ну то есть то, что орлы в MS не смогли корректно реализовать IDisposable — это от избытка энергии?


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

S> А я-то дурак думал, это от того, что понять, когда вызывать Dispose на мембере, не всегда так легко, как хотелось. Я тебе еще десяток могу примеров привести, но они, в отличие от System.Drawing.Image, будут вымышленными.


Во-вот. Вымешленных. Это все и объясняет. А по жизни я что-то проблем не встречаю.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Смотрел на Java код. ...много думал.
От: desperado_gmbh http://www.livejournal.com/users/tolstopuz
Дата: 07.11.05 13:58
Оценка: +3 :))) :)
Здравствуйте, VladD2, Вы писали:

VD>Это с непривычки. Когда появились Фортран, С и Паскаль народ долгое время упиравшися в работу максимум на уровне ассемблеров, а в основном машинных кодов, тоже не весь сразу оценил приемущество языков высокого уровня. По началу тоже не видили приемуществ. Точнее считали что недостатки (тормоза ведь какие?!) перевешивали.


При настоящем состоянии телеграфа без проводов нельзя предаваться чрезмерным надеждам на быстрое его развитие. Стоимость эксплуатации беспроводного телеграфа слишком высока, чтобы он в современном виде сделался всеобщим достоянием. Передача нескольких слов требует непрерывного действия довольно крупных машин, потребляющих много энергии, значительная часть которой непроизводительно рассеивается в пространстве. К недостаткам следует отнести также медленность действия беспроводного телеграфа.
Re[8]: Смотрел на Java код. ...много думал.
От: LeeMouse Россия  
Дата: 07.11.05 14:47
Оценка: -1
Здравствуйте, VladD2, Вы писали:

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


Про умные указатели не слыхали? Или вспомнить религия не позволяет?
Re[10]: Смотрел на Java код. ...много думал.
От: LeeMouse Россия  
Дата: 07.11.05 14:53
Оценка: +1 -1 :)
Здравствуйте, savaDAN, Вы писали:

E>>Какие-такие смартпоинтеры, которые толком не поддерживаются компилятором.

DAN>Ну например о которых Джэф Элджер в С++ библиотека программиста пишут.
DAN>ИМХО, сказать что эти сущности полностью поддерживаются компилятором (в том смысле что не позволят программисту допустить ошибку с управлением памятью) — нельзя.

А что, .NET языки полностью исключают ошибку программиста? Может они тогда и программы сами писать уже умеют?

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


Что значит "не поддерживается компилером"? Вот у меня уже не первый десяток проектов с пулами потоков и распределенным взаимодействием на С++ сдано в эксплуатацию, и что-то как-то не нарываюсь на меморилики.... видимо не судьба...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.