Здравствуйте, Аем Вопля, Вы писали:
АВ>Отклонение от темы началось с вот этого вашего сообщения: АВ>«Офигеть! А почему мы тогда не говорим о вредном воздействии java-программ на вселенскую энтропию?»
Напротив, сударь — это была попытка вернуть Вас к начатой в ветке теме, а именно к проблемам с утечками памяти.
АВ>Прекратим диалог на этом.
Как Вам будет угодно. Тем более, что судя по всему, сказать по сути Вы толком ничего не можете. Надеюсь диалог с MasterZiv окажется более плодотворным.
Пацак пишет:
> Вопрос в том, так ли уж часто это надо пользователю. Как правило если > пользователь хочет "не думать о файлах", то он хочет не думать именно о > файловом вводе/выводе вообще, получив взамен нечто более высокоуровневое > — типа, скажем, такого:
Это — ровно то самое, о чём я написал.
И это — уход от темы, потому как вы подменяете одно другим.
Я говорю о случае, когда от файла человеку ничего более не нужно,
кроме как просто ввода-вывода. Вы же говорите о более "высокого уровня"
случае, когда применение стратегий будет уже оправдано.
Я говорю, что в таком примитивном случае pattern-based машинерия Java
НЕ РАБОТАЕТ, потому что слишком тяжела для такого простого случая,
вы же делаете случай гораздо более сложным, и говорите, что такая
машинерия работает в этом случае. Я спорить не буду, да, работает,
но СЛУЧАЙ ДРУГОЙ. И в других языках тут ничем это не будет отличаться --
для разбора XML-я или рег.выражения в C++ или PERL наверное будут
использоваться подобные же подходы.
Но случай с открытием файла — это лишь ПРИМЕР того, где технология
Java (с нашей точки зрения) "лажает". Нет смысла рассматривать
другой пример и доказывать, что там она "не лажает".
Пацак пишет:
> Как Вам будет угодно. Тем более, что судя по всему, сказать по сути Вы > толком ничего не можете. Надеюсь диалог с MasterZiv окажется более > плодотворным.
Да, вас явно занесло. Наверное, обоих, потому как я не понял, кто начал.
Классно, спасибо.
Добавил страницу в закладки, буду читать перед сном, и
давать в виде ссылки всем тем, кто думает, что GC решает все проблемы
на свете.
Не, реально, даже само название статьи торкает конкретно:
"Handling memory leaks in Java programs". !!!
opener пишет:
> Насколько сложно перейти на Java после С++? Проще/сложнее сама жаба по > сравнению с С++? По моим нынешним представлениям вроде проще. И какого > тогда хрена у жаба-программистов зарплаты больше?
Что-то мы тут (в теме) сильно отошли кажется от темы эхотага.
Я искренне не виноват. А если виноват — каюсь.
Может быть модератор с соглашения автора сочтёт возможным
перенаправить нас на путь истенный, типа в философии, или ещё где ?
Я извиняюсь за самомодерирование...
Здравствуйте, MasterZiv, Вы писали:
MZ>Это — ровно то самое, о чём я написал.
Возможно я пропустил... Где именно?
MZ>И это — уход от темы, потому как вы подменяете одно другим. MZ>Я говорю о случае, когда от файла человеку ничего более не нужно, MZ>кроме как просто ввода-вывода. Вы же говорите о более "высокого уровня" MZ>случае, когда применение стратегий будет уже оправдано.
Ну я, собственно, пытаюсь разобраться — а так ли уж часть программистам нужен "просто файловый ввод-вывод"? Насколько я могу судить, обычно на одного core-developer'а, занимающегося работой с ресурсами, приходится десяток-два "пользователей" его кода, работающих с более высокоуровневыми понятиями — документами, архивами, конфигурациями etc. И с точки зрения инкапсуляции, им должно быть совершенно безразлично, как именно внутри организованы его классы.
MZ>Но случай с открытием файла — это лишь ПРИМЕР того, где технология MZ>Java (с нашей точки зрения) "лажает".
Зависит от ситуации. Можно сходу придумать пример, где освобождение ресурсов в деструкторе будет создавать неудобства и потенциальные ошибки. Что, например, произойдет, если плюсовая функция вернет указатель на открытый в локальном контексте файл? А если дочерняя функция начнет чтение из него в отдельном потоке? Автоматические деструкторы сами по себе — не панацея и не освобождают от необходимости думать и следить за стилем кодирования. По крайней мере имхо делают это гораздо реже и в меньшей степени, чем garbage collector в java.
Здравствуйте, MasterZiv, Вы писали:
MZ>Не, реально, даже само название статьи торкает конкретно: MZ>"Handling memory leaks in Java programs". !!!
Правильнее было бы назвать статью "Emulating memory leaks in Java programs", т.к. по сравнению с реальной утечкой памяти (когда средствами языка ее уже невозможно вернуть в использование) рассматриваемая в ней ситуация имеет куда более тривиальный характер — память всего лишь нерационально используется, только и всего. Да, это плохо и может привести к проблемам (довольно редко, впрочем), но конкретно к java как таковой отношения не имеет — умеючи, того же эффекта можно добиться практически на любом языке.
Здравствуйте, MasterZiv, Вы писали:
MZ>Может быть модератор с соглашения автора сочтёт возможным MZ>перенаправить нас на путь истенный, типа в философии, или ещё где ? MZ>Я извиняюсь за самомодерирование...
Вроде бы на rsdn самомодерирование даже приветствуется — если делать его через "бомбочки". Я свою повесил на головное сообщение — за перенос в "философию программирования". Предлагаю сделать так же.
Здравствуйте, alexeiz, Вы писали:
LVV>>1. Меня лично напрягала необходимость обязательно писать обработку исключений.
A>Что в Java в этом плане лучше?
Я так понимаю, что имелось в виду следующее: если в каком-то методе возникает исключение, то ты должен либо явно обработать его, либо явно же добавить его к описанию этого метода. В последнем случае его надо будет (опять же явно и обязательно) обработать где-то выше. Например:
// Так можно - исключение декларируетсяvoid foo1() throws MyException {
throw new MyException();
}
// И так тоже - исключение обрабатываетсяvoid foo2() {
try {
throw new MyException();
} catch (MyException e) {
// do smth
}
}
// А вот так - уже нет. Нужно определить либо то, либо тоvoid foo3() {
throw new MyException();
}
С++ в этом плане более лоялен, а в java эти строгости действительно иногда напрягают. Впрочем, польза от них тоже есть — глядя на код сразу видно, где и какой конкретно shit может happens. Так что это, как обычно, палка о двух концах...
Пацак пишет:
> С++ в этом плане более лоялен, а в java эти строгости действительно > иногда напрягают. Впрочем, польза от них тоже есть — глядя на код сразу > видно, где и какой конкретно shit может happens. Так что это, как
На самом деле в Java можно делать и так, и так, т.е. и как в С++.
В Java есть два вида исключений: простые (можно сказать strict) и Runtime
Exceptions.
Runtime Exceptions обрабатываются ровно так же в смысле обязательности
перехвата, как и в С++, т.е. их перехватывать либо объявлять не обязательно. То
есть в принципе можно было бы делать и
так, и так, сочетая при этом всё в одной программе.
Но только :
-- решение об этом принимает разработчик класса, а не пользователь
-- многие программисты либо вообще не знают про такие возможности, либо
не понимают преимуществ Runtime Exceptions, или тупо не хотят разбираться
с этим.
И в итоге наверное подавляющее большинство исплючений в реальном
коде Java — strict.
Здравствуйте, Аем Вопля, Вы писали:
АВ>Ладно, я вижу, шутки вы не поняли.
Чтобы шутку понимали, она должна быть смешной.
АВ>Такие ситуация обычно и называется утечкой ресурсов.
Так вот ещё раз повторяю вопрос: причём здесь утечка памяти ?
АВ>И основная проблема как раз в том, что вызывать Dispose нужно вручную, отслеживая все ветви выполнения, а это ничем не лучше старого доброго C,
Если необходимо детерминированное освобождение ресурса, то нужно хоть что-то, но написать. Других вариантов нет. И "в отличии от", в Java хотя бы try/finally есть.
АВ>хотя, казалось бы, с появлением GC все должно делаться автоматически.
Ну так если Dispose() явно не вызовете, оно, в итоге, автоматически и сделается. Когда наступит момент срабатывания GC, он вызовет соответствующий finalizer и все неуправляемые ресурсы занятые FileStream'ом освободятся. Управляемые освободятся обычным образом: как только живые ссылки исчезнут и сработает GC.
АВ>И тут оказывается, что C++ имеет даже некоторое преимущество в этом отношении, так как поддерживает автоматический вызов деструкторов при выходе из области видимости.
Распространённое заблуждение. В деструкторе C++ можно разместить процедуры освобождения только для элементарных ресурсов. Прежде всего "чистых" объектов в памяти. Любой ресурс с нетривиальной логикой освобождения, например, распределённая транзакция, и облом-с. Бо из деструктора нельзя нормальным образом передать информацию о возникновении ошибочной ситуации в процессе этого самого освобождения.
Кстати, ifstream из Вашего примера, тоже образец нетривиального ресурса. Бо закрытие файла может вызывать ошибочные ситуации. И чтобы их увидеть, потребуется явный вызов rdbuf()->close()
АВ>Допустим, это может быть создание объектов в цикле.
Создавайте. В чём проблема ? Даже больше скажу, если это строго локальный объект цикла, то есть вероятность, что JIT сгенерит код, который больше одного такого и не создаст, а просто станет переиспользовать один и тот же объект.
АВ>Неграмотное использование GC легко может привести к созданию программы, низкая эффективность которой не влезет ни в какие ворота.
"Я плакаль" (c) не мой
Неграмотное использование C++ может к такому привести... Мне вот даже думать об этом страшно
Как раз в системе с GC, низкоквалифицированный разработчик напишет нормальный (относительно) код с гораздо более высокой вероятностью, чем в системе без оного.
*Уж поверьте человеку, который каждый год видит результаты "подвигов" студентов как на C++, так и на Java.
АВ>А GC — это такая «квазиавтоматика», когда ты все равно должен держать в голове, как этот GC работает.
GC есть система управления памятью. И, как и любую другую систему управления памятью, её, разумеется, надо знать и понимать.
АВ>И на практике получается так, что из-за GC управление ресурсами в .Net и Джаве становится местами даже еще более «ручным», чем в C++.
См. выше. Это Вам кажется от обилия всяких там smart pointer'ов и тому подобной ерунды в C++ коде. В Java всё это ненужно, бо GC как раз и решает данные проблемы.
АВ>Я не прав? Если я не прав, зачем тогда ввели ключевое слово using в C#, а? Если и так все «автоматическое»?
Для упрощения управления ресурсами отличными от памяти.
Здравствуйте, MasterZiv, Вы писали:
MZ>На самом деле в Java можно делать и так, и так, т.е. и как в С++.
Можно, но подменять одно другим — считается несколько дурным тоном. И в общем-то практически никогда это не бывает нужно — за исключением разве что случая, когда нужно переопределить метод предка, но добавить к нему выброс еще одного типа исключения не позволяет синтаксис. Тут приходится извращаться — оборачивать checked exception в runtime exception, а потом извлекать снаружи. Но тут надо четко понимать, что кроме конкретно этого нашего кода этот метод может использоваться и в других местах, где никто не ждет выброса необъявленного исключения и поэтому оно может привести к непредсказуемым последствиям. Так что опять же — и хорошо и плохо, it depends.
Тут приходится > извращаться — оборачивать checked exception в runtime exception, а потом > извлекать снаружи. Но тут надо четко понимать, что кроме конкретно этого > нашего кода этот метод может использоваться и в других местах, где никто > не ждет выброса необъявленного исключения и поэтому оно может привести к > непредсказуемым последствиям.
Чтобы в Java НЕ ЖДАЛИ появления RuntimeException, которое по сути своей
непредсказуемо появляется, -- это новость какая-то.
drol пишет:
> Ну так если *Dispose()* явно не вызовете, оно, в итоге, автоматически и > сделается. Когда наступит момент срабатывания GC, он вызовет > соответствующий finalizer и все /неуправляемые/ ресурсы занятые > *FileStream*'ом освободятся. Управляемые освободятся обычным образом: > как только живые ссылки исчезнут и сработает GC.
Вы пишите на Java finalizer-ы ?
Потом, ключевая фраза тут "когда наступит момент срабатывания GC".
А он, вообще-то, может и никогда не наступить.
> Распространённое заблуждение. В деструкторе C++ можно разместить > процедуры освобождения только для элементарных ресурсов. Прежде всего > "чистых" объектов в памяти. Любой ресурс с нетривиальной логикой > освобождения, например, распределённая транзакция, и облом-с. Бо из > деструктора нельзя нормальным образом передать информацию о > возникновении ошибочной ситуации в процессе этого самого освобождения.
Да пожалуйста, передавайте. Сохраните только предварительно внутри
этого объекта.
Ладно, я не вижу что тут можно ещё спорить или доказывать.
Здравствуйте, MasterZiv, Вы писали:
MZ>Вы пишите на Java finalizer-ы ?
Нет, бо не работаю (промышленно) на Java уже более трёх лет. Сейчас я их пишу на C#, точнее пишу то что из finalizer'ов вызывается.
MZ>Потом, ключевая фраза тут "когда наступит момент срабатывания GC". MZ>А он, вообще-то, может и никогда не наступить.
Типа удивили. Вызов деструктора C++ тоже может никогда не наступить. Какой-нибудь kill -9 и "до свидания, друзья, до свидания..."
>> Бо из >> деструктора нельзя нормальным образом передать информацию о >> возникновении ошибочной ситуации в процессе этого самого освобождения.
MZ>Да пожалуйста, передавайте. Сохраните только предварительно внутри MZ>этого объекта.
Какого объекта ? Объекта уже нет. Фигня ведь случилась в автоматическом вызове деструктора.
MZ>Ладно, я не вижу что тут можно ещё спорить или доказывать.
Здравствуйте, CreatorCray, Вы писали:
CC>Вот мне всегда было непонятно, почему в плюс языка всегда пытаются отнести большую стандартную библиотеку?
Потому что хороший современный язык обязан быть спроектирован в том числе и с учетом простоты и удобства как создания фреймворков, так и их использования. А для С++ даже ABI все никак не устаканят.
... << RSDN@Home 1.2.0 alpha 4 rev. 1137 on Windows Vista 6.0.6001.65536>>