Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.12.16;
Скачать: [xml.tar.bz2];

Вниз

delphi = pascal = языки для начинающих   Найти похожие ветки 

 
Однокамушкин   (2007-11-15 11:38) [240]


> Так что особо мешает подшивать для таких вот объектов отслеживание
> ссылок по месту? Когда ссылки исчезли - дергаем Close,

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


 
Romkin ©   (2007-11-15 11:41) [241]


> Мешает то, что счётчик ссылок работает только для простых
> типов вроде string-ов, а когда есть циклические ссылки двух
> объектов друг на друга и больше никаких, счётчик ссылок
> не поможет, тут нужен более сложный алгоритм определения
> того, что на объекты нет доступных извне ссылок - тот самый
> алгоритм, который и реализует GC

Почему-то в COM этому ничего не мешает.


 
Piter ©   (2007-11-15 11:44) [242]

Romkin, а почему FreeLibrary не приводит к мгновенной выгрузке библиотеки?
А почему даже завершение процесса, который единственный использует некую библиотеку - не приводит мгновенно к выгрузке этой библиотеки физически из памяти?

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

Юрий Зотов ©   (15.11.07 2:48) [220]
Миш, ты никак не мог лучше подтвердить мои слова о том, что ты не вполне понимаешь, что такое ресурсы


о, да. Я вообще ламер ;)

Юрий Зотов ©   (15.11.07 2:48) [220]
Какие сборщики мусора будут тебе хэндлы закрывать?


хэндл - такой же нетипизированный объект, просто число - одной windows и системным таблицам в ВАП процесса известно к чему это относится. Ну и логике программиста, если он не забудет откуда это число.
А в Java не должно быть никаких хендлов.


 
Evgeny V ©   (2007-11-15 11:50) [243]


> Юрий Зотов ©   (15.11.07 10:49) [236]


IDispoSible не спасет, все равно надо явно вызывать Close или Dispose. В JAVA

есть методы Dispose, Close, есть интерфейс CloseAblr. Для своих классов сделать интерфейс не проблема. Все равно надо вызывать и там и там, если хотите немедленного освобождения ресурсов.


> Romkin ©   (15.11.07 11:32) [239]

Ей богу не знаю, я бы не был против, если бы это было быстро:-)


 
DiamondShark ©   (2007-11-15 11:56) [244]


> Система (VM, но никак не вызывающая сторона!) обязуется,
>  в случае, если у объекта экспонируется этот интерфейс,
> вызвать его метод Close как можно быстрее после момента,
>  когда на объект перестали ссылаться.
> Неужели это сложно?

Давай смотреть.

1. В методе Close доступен this, а это значит, что побочным эффектом метода Close может стать то, что на объект снова начнут ссылаться. Что должна делать система в этом случае?

2. С учётом (1) в многопоточном окружении объект может сколько угодно раз становиться доступным и недоступным, параллельно с выполнением метода Close. Что должна делать система в этом случае?

3. В момент обнаружения недоступности объекта как поток, создавший объект, так и поток, обнуливший последнюю ссылку могут уже не существовать. В контексте какого потока будет выполняться метод Close? Как скажется на ресурсах их выделение и освобождение в контексте разных потоков? Что делать с ресурсами, которые не допускают освобождение в контексте потока, отличного от создающего (например, window handle)?

4. Подсчёт ссылок не гарантирует освобождение объекта, существует проблема циклических ссылок, поэтому GC использует другой метод определения доступности объекта. В какое место алгоритма GC встроить вызов метода Close?


 
Romkin ©   (2007-11-15 11:59) [245]


> Romkin, а почему FreeLibrary не приводит к мгновенной выгрузке
> библиотеки?А почему даже завершение процесса, который единственный
> использует некую библиотеку - не приводит мгновенно к выгрузке
> этой библиотеки физически из памяти?

Ты мелкое с мягким не путай :)
У тебя получается - в огороде бузина а в Киеве дядька.
Да, в java нет хендла. И слава богу. Там есть Stream, объект. Так почему я должен сам определять момент, когда он мне становится не нужен, и вызывать его метод Close?
И что, по-твоему, внутри этого объекта Stream нет хендла? Я сильно сомневаюсь. Он есть, может быть, где-то поглубже. И хендл это или объект - сути не меняет. Можешь считать, что объект держит файл.
Я хочу, чтобы некоторые ресурсы освобождались сразу, как только становятся не нужны. Встроенного механизма для этого в java нет. Все. О чем дальнейший разговор-то?


 
DiamondShark ©   (2007-11-15 12:03) [246]


> Romkin ©   (15.11.07 11:41) [241]
>
> Почему-то в COM этому ничего не мешает.

Очень мешает. Повисшие циклические ссылки могут сильно насолить. Зависнут два объекта, занявшие ресурсы, и привет.
Попишите подольше на чём-нибудь не просто время от времени использующем COM, а прямо таки пропитанным им насквозь.
Вроде Акцесса.


 
@!!ex ©   (2007-11-15 12:04) [247]

> [246] DiamondShark ©   (15.11.07 12:03)

Пишу на DirectX. Все на COM.
Проблем нет.


 
DiamondShark ©   (2007-11-15 12:05) [248]


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

Вызывай Close. В чём проблема? Лень пять букв написать?


 
Evgeny V ©   (2007-11-15 12:06) [249]

DiamondShark ©   (15.11.07 11:56) [244]

3. В момент обнаружения недоступности объекта как поток, создавший объект, так и поток, обнуливший последнюю ссылку могут уже не существовать. В контексте какого потока будет выполняться метод Close? Как скажется на ресурсах их выделение и освобождение в контексте разных потоков? Что делать с ресурсами, которые не допускают освобождение в контексте потока, отличного от создающего (например, window handle)?


 
Evgeny V ©   (2007-11-15 12:07) [250]

Дополнение к Evgeny V ©   (15.11.07 12:06) [249]  - этот пункт как раз таки решен - у GC свой поток


 
DiamondShark ©   (2007-11-15 12:08) [251]


> @!!ex ©   (15.11.07 12:04) [247]

А я за всю жизнь не видел ни одного китайца живьём.
Значит ли это, что китайцев нет?


 
DiamondShark ©   (2007-11-15 12:10) [252]


> этот пункт как раз таки решен - у GC свой поток

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


 
Dimka Maslov ©   (2007-11-15 12:12) [253]

Если паскаль – язык для начинающих, тогда java – для заканчивающих.


 
Romkin ©   (2007-11-15 12:13) [254]

DiamondShark ©   (15.11.07 11:56) [244]
Что-то мне подсказывает, что ответы уже есть в .NET
Замечу, что для "ручного" вызова метода close существуют практически те же проблемы.


 
Romkin ©   (2007-11-15 12:15) [255]

DiamondShark ©   (15.11.07 12:05) [248] Ты не читаешь, что пишет, например, Зотов?


 
DiamondShark ©   (2007-11-15 12:19) [256]


> Romkin ©   (15.11.07 12:13) [254]
> Что-то мне подсказывает, что ответы уже есть в .NET

Нет.
Дотнетовский IDisposable работает не так.


> Замечу, что для "ручного" вызова метода close существуют
> практически те же проблемы.

Да-а?! Ну, пусть так. Тогда и для ручного вызова деструктора в дельфях и плюсах "существуют практически те же проблемы", потому что классический деструктор и метод close ничем не отличаются.
Тогда вопрос: так в чём же, блин, суть претензий?


 
DiamondShark ©   (2007-11-15 12:21) [257]

Удалено модератором
Примечание: Выражения выбираем


 
@!!ex ©   (2007-11-15 12:24) [258]

> [257] DiamondShark ©   (15.11.07 12:21)

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

После Destroy ничего не остается.


 
Romkin ©   (2007-11-15 12:29) [259]


> Да-а?! Ну, пусть так. Тогда и для ручного вызова деструктора
> в дельфях и плюсах "существуют практически те же проблемы",
>  потому что классический деструктор и метод close ничем
> не отличаются.Тогда вопрос: так в чём же, блин, суть претензий?
>

В том, что, понимаешь, в Delphi я могу сам управлять временем жизни объекта. А в java у меня этой возможности просто нет. Ее вырубили. И этим, простите, создали проблему. Какую - см. посты Зотова, мне кажется, он толково ее обозначил.
Недоделка.  
Почему в Delphi я могу писать в стиле [229], а в java - нет?
Заметь, в приведенном коде нет ни вызова close, ни вызова деструктора. При этом все работает, млин. И не то что в разных потоках, в разных приложениях.


 
Игорь Шевченко ©   (2007-11-15 12:30) [260]

Romkin ©   (15.11.07 12:29) [259]

Писать надо на ассемблере. На худой конец - на Прологе.


 
Romkin ©   (2007-11-15 12:31) [261]


> Тем что после вызова Close остается вполне рабоий объект
> без данных, которые были убиты Close.После Destroy ничего
> не остается.

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


 
Юрий Зотов ©   (2007-11-15 12:35) [262]

> Romkin ©   (15.11.07 12:29) [259]

Ром, бесполезно. Иногда бесполезно. И ты знаешь, почему.


 
@!!ex ©   (2007-11-15 12:57) [263]

"Приходя на кухню, каждую неделю видя переполненную сахарницу и рассыпанный вокруг неё сахар удивлялся, а тут вдруг осенило: вокруг меня на этаже только Java девелоперы -нету привычки ни выделять достаточно места под буффер перед его заполнением, ни удалять за собой использованные объекты."(С) БОР


 
clickmaker ©   (2007-11-15 13:07) [264]

Java девелоперам вообще не сладко.
Смотрите, какой мизер им предлагают. Хорошо, хоть сахар бесплатно

Senior Java developer
Город: Санкт-Петербург
Работодатель: Sunrise-r SPb
Уровень зарплаты: от 40 до 45 руб.


 
palva ©   (2007-11-15 13:11) [265]

вокруг меня на этаже только Java девелоперы
У Delphi- или Basic-разработчиков тоже нет нужды думать о буферах при работе со строкой. Наверно поэтому слишком часто приходится видеть неэффективный код связанный с созданием и удалением промежуточных строк при всякого рода динамических конструированиях строк. Некоторые программисты используют для подобного конструктора самодельную домашнюю заготовку -  что-то вроде StringBuilder в .NET Но начинающие как правило этим не заморачиваются, а педагоги и не советуют. Ибо нестандартно.


 
Piter ©   (2007-11-15 13:15) [266]

Romkin ©   (15.11.07 11:59) [245]
И что, по-твоему, внутри этого объекта Stream нет хендла? Я сильно сомневаюсь


ну внутренняя реализация тебя касаться не должна.

Romkin ©   (15.11.07 11:59) [245]
Так почему я должен сам определять момент, когда он мне становится не нужен, и вызывать его метод Close?


можешь не вызывать.

Если ты повторно откроешь этот файл из Java - он уже не откроется по причине занятости разве?

Romkin ©   (15.11.07 11:59) [245]
Я хочу, чтобы некоторые ресурсы освобождались сразу, как только становятся не нужны


вызывай Close. В чем проблема то?

По сути, тебе не нравится то, как работает сборщик мусора в java. Но он работает не так, как ты хочешь в свете аспекта освобождения ресурсов, а по другим критериям. Поэтому я привел пример с FreeLibrary, ты может и хочешь, чтобы DLL выгрузилась сразу при обнулении ссылок, но windows из своих расчетов так не работает. Вот и все. И методов стопроцентно выгрузить библиотеку из памяти нету.

Romkin ©   (15.11.07 12:29) [259]
в Delphi я могу сам управлять временем жизни объекта. А в java у меня этой возможности просто нет


вот именно. Потому что java - язык с самостоятельным управлением жизнью объекта и сборщиком мусора. Не нравится такой подход - пожалуйста, не используй, в чем проблема?

По-моему, это все равно что говорить, ассемблер - говно, так как в нем нет ООП.


 
Romkin ©   (2007-11-15 13:21) [267]


> ну внутренняя реализация тебя касаться не должна.

Вот именно! К этому, собственно, и стремлюсь. Но тут-то меня она касается, потому что я должен знать, что надо вызвать метод Close.
Замечаешь логику? Для того, чтобы удачно использовать такой объект, я должен обладать информацией о его внутреннем устройстве, пусть и опосредованной!
Иначе как трактовать фразу: "Чтобы объект освободил ресурс, ты должен вызвать метод Close"? Опаньки! По-твоему, это не информация о внутреннем устройстве объекта?


 
DiamondShark ©   (2007-11-15 13:24) [268]


> Romkin ©   (15.11.07 12:29) [259]

Ладно. Давай разбираться.

Вспомним для начала турбо паскаль. Там объекты вообще не обязаны были иметь какой-либо деструктор. Могли никакого не иметь. И операции управления памятью и инициализации/финализации объекта были разделены: были операторы New и Dispose, наряду с конструкторами/деструкторами.

Зотов сначала сказал, что это именно автоматическое управление памятью мешает ему работать. Но это -- [выбранное выражение], потому что если б он свою задачу в такой же постановке (есть куча объектов непоймикакого класса) решал на турбо паскале, у него бы возникла точно такая же проблема: неизвестно, чего у объекта вызывать для освобождения, потому что как называется деструктор и есть ли он вообще -- неизвестно.
Вывод: ни GC, ни вообще какой иной протокол управления памятью тут совершенно ни при чём.
Fixed?

("Доверили бы вы аэропорт программе на турбопаскале")

Между прочим, у стримов в TurboVision был метод Close, потому что объекты в турбопаскале можно было создавать не только в куче, но и статически и на стеке, а деструкторов могло быть сколько угодно, в том числе и ноль. Да и оператор Dispose можно было вызвать без указания деструктора.
Опять видим, что процедура управления памятью к освобождению ресурсов имеет отношение весьма слабое.

Идём дальше.

Как писали на турбопаскале? А первым делом создавали класс с пустым виртуальным деструктором, и от него наследовали всё остальное. Иными словами сами руками создавали себе нужный интерфейс. Это оказалось настолько продуктивным, что Борланд сначала включил такой объект в библиотеку TurboVision, а потом вообще вынес на уровень языка.

Почему в языках с ручным управлением памятью так важно наличие виртуального (или по умолчанию, как в плюсах) деструктора? А именно для того, чтобы иметь возможность удалять граф взаимно ссылающихся объектов! Это единственно возможный способ освободить память, без виртуального деструктора вообще невозможно было бы программировать с использованием таких объектов. Именно это обстоятельство обусловило тот факт, что все объекты в языках с ручным управлением памятью снабжены интерфейсом, содержащим виртуальный деструктор.
Возможность навесить на деструктор ещё что-то, кроме освобождения взаимных ссылок, явилась приятным, но совсем не обязательным бонусом.

Однако, дельфисты, видимо, настолько привыкли к совмещению операций управления памятью и инициализации/финализации объекта, что стали считать это не одной из возможностей, а чем-то вроде священной истины.

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

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


 
Romkin ©   (2007-11-15 13:31) [269]


> Однако, дельфисты, видимо, настолько привыкли к совмещению
> операций управления памятью и инициализации/финализации
> объекта, что стали считать это не одной из возможностей,
>  а чем-то вроде священной истины.

Брр! Я речь разве об этом вел? Или Зотов?

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

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


 
DiamondShark ©   (2007-11-15 13:33) [270]


> Опаньки! По-твоему, это не информация о внутреннем устройстве
> объекта?

Это информация об интерфейсе объекта.
Тебя ж не смущает необходимость знания, вроде: "Для того, чтобы нарисовать буковки, надо вызвать метод DrawText".

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


 
Romkin ©   (2007-11-15 13:39) [271]

Поясню, опять же на примере с потоками: function BigBrother.GetMeTheData: IStream;
begin
 //Что здесь?
end;

//Пользуем, где-то:

procedure ReadFile;
var
Stream: IStream;
begin
Stream := BigBrother.GetMeTheData;
Stream.Read(...);
//Big thanks!
end;

Вот что у меня может быть в первой функции? Я могу взять поток от адаптера, захватив файл, могу - через вызов GetStreamOnHGlobal дать кусок памяти, могу свой объект сделать, который данные на лету создавать будет.
Вызывающая сторона знает, что там внутре? Нет. Совсем. И не ее это забота. Более того: ей запрещено вообще делать предположения о том, где лежит данный ей объект и как он устроен.
Вот именно это и называется полной капсуляцией.


 
Romkin ©   (2007-11-15 13:43) [272]


> Это информация об интерфейсе объекта.Тебя ж не смущает необходимость
> знания, вроде: "Для того, чтобы нарисовать буковки, надо
> вызвать метод DrawText".

Э, нет. Дергание Close нужно тому объекту, который ты используешь, но никак не тому, который его использует: ему-то какой с этого прок? Ресурсы не его!
А вот DrawText нужен именно использующему объекту.
Слушай, ты действительно не понимаешь, о чем речь?


 
DiamondShark ©   (2007-11-15 13:47) [273]


> Romkin ©   (15.11.07 13:31) [269]
>
> Брр! Я речь разве об этом вел? Или Зотов?

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


> Вот именно. Сам.

Ну извини. В Дельфи нужный интерфейс реализовал дядя, а тут тебя напрягли.
Посчитай в каком-нибудь более-менее объёмном проекте количество классов, захватывающих ресурсы отличные от памяти, и сам реши, должен ли кто-то напрягаться, чтоб решить 1% твоих личных проблем.
Прими во внимание, также, тот факт, что объекты, типа, стримов, дбконнектов и прочих сокетов (т.е. 99.9% всех ресурсозахватывающих объектов) либо используются по сценарию открыл-поюзал-закрыл, либо находятся по хорошо известным на момент разработки специфически типизированным ссылкам, т.е. не вписываются в зотовский сценарий "куча объектов непойми-какокого класса".

Ну и из-за чего вы с Зотовым подняли гевулт? Зотов на высосанном из пальца "реальном примере" дизайна задней ногой, а ты -- вообще на пустом месте.


 
Romkin ©   (2007-11-15 13:52) [274]


> Ну и из-за чего вы с Зотовым подняли гевулт? Зотов на высосанном
> из пальца "реальном примере" дизайна задней ногой, а ты
> -- вообще на пустом месте.

Хм. Класс в java должен заботиться о сохранности ресурсов другого класса. Инкапсуляция разлетается вдребезги. Действительно, пустое место и остается.


 
DiamondShark ©   (2007-11-15 13:53) [275]


> Romkin ©   (15.11.07 13:39) [271]

Я в дотнете пишу
using (Stream stm=BigBrother.GetMeTheData())
{
 stm.Read(...);
 stm.Read(...);
}

В яве будет try...finally c close.

Весь шум из-за двух строчек кода?


 
DiamondShark ©   (2007-11-15 13:57) [276]


> Romkin ©   (15.11.07 13:52) [274]
> Хм. Класс в java должен

Не класс, а программист.

У тебя есть контракт класса, в котором сказано: уходя гасите всех.
В чём проблема?

Вот еслиб у тебя был класс не с методом

DrawText(x, y, str)

а с парой

MoveTo(x, y);
DrawText(str);

ты бы тоже стал возмущаться "А! Меня заставляют знать о каких-то там текущих x, y!"?


 
DiamondShark ©   (2007-11-15 13:58) [277]


> Инкапсуляция разлетается вдребезги

Угу. Вместе с боингами в аэропорту.

Без истерик можно?


 
Черный Шаман   (2007-11-15 14:37) [278]


> Юрий Зотов ©   (15.11.07 02:44) [219]
>
> > Черный Шаман   (15.11.07 01:50) [215]
>
> В [80] я привел код теста, который показывает, что finalize
> не вызвался ни разу за все время жизни приложения (хотя
> счетчик ссылок на объект обнулялся, как минимум, дважды).
>  Как это понимать? Очевидно, так, что за все время жизни
> приложения GC ни разу не решил, что пора почистить память.
>  По крайней мере, других объяснений нет.
>
> Но возникает вопрос - а если бы объект открыл файл или коннект
> к БД, а код его освобождения был прописан именно в finalize
> (кстати, в полном соответствии с рекомендациями документации)
> то что, этот ресурс так и остался бы открытым? Чушь ведь.


Нет не чушь. Хотите более детерминированного освобождения сами вызывайте GC, хотя это делфийский вариант "прогнать все переменные".

GC вызывается не когда угодно, а когда не хватает свободной памяти.


 
Юрий Зотов ©   (2007-11-15 15:00) [279]

> Черный Шаман   (15.11.07 14:37) [278]

>> Но возникает вопрос - а если бы объект открыл файл или коннект
>> к БД, а код его освобождения был прописан именно в finalize
>> (кстати, в полном соответствии с рекомендациями документации)
>> то что, этот ресурс так и остался бы открытым? Чушь ведь.

> Нет не чушь.

Чи-го? Программа завершилась, ресурс остался открытым - и это не чушь?

Нет, вот с ЭТИМ я уж точно спорить не стану.


 
Piter ©   (2007-11-15 15:04) [280]

Юрий Зотов ©   (15.11.07 15:00) [279]
Чи-го? Программа завершилась, ресурс остался открытым - и это не чушь?


программа завершилась, а библиотека так и не была выгружена из памяти, впрочем как и образ EXE. Это же вы чушью не считаете почему-то?

Программа завершилась, а ресурс остался открытым?



Страницы: 1 2 3 4 5 6 7 8 9 
10 11 вся ветка

Форум: "Прочее";
Текущий архив: 2007.12.16;
Скачать: [xml.tar.bz2];

Наверх




Память: 1.11 MB
Время: 0.136 c
4-1180166777
Ganda
2007-05-26 12:06
2007.12.16
Подключить 32 битную библиотеку к 16 битному приложению.


11-1181055188
=BuckLr=
2007-06-05 18:53
2007.12.16
То, что у меня не работает в RichEdit


15-1194910495
guard_gg
2007-11-13 02:34
2007.12.16
Кто знает си++? Помогите пожалуйста. Совсем простой вопрос.


15-1195127822
alex_***
2007-11-15 14:57
2007.12.16
аналог self в vb6


2-1195500252
GREENGENERAL
2007-11-19 22:24
2007.12.16
Компонент по типу StringGrid, но чтобы пользователь мог изменять





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский