|
23.03.2007, 10:58 | #1 |
Участник
|
Создание экземпляра класса Dict*
Предлагаю вниманию такой код
X++: static void JobXXXX(Args _args) { DictTable dictTable; HeapCheck hc = new HeapCheck(); ; info (strfmt("Кол-во объектов в памяти до создания %1", hc.countObjects(classnum(DictTable)))); dictTable = new DictTable(0); if (dictTable == null) info("Проверка на NULL вернула истину"); info (strfmt("Кол-во объектов в памяти после создания %1", hc.countObjects(classnum(DictTable)))); dictTable = null; info (strfmt("Кол-во объектов в памяти после присвоения NULL %1", hc.countObjects(classnum(DictTable)))); } В принципе , такая проверка безопасна, она не позволит обратиться к методам такого класса.Но, пока dictTable (в принципе, это касается всего семейства классов Dict*) находится в области видимости, объект остается в памяти. По-моему, это ведет к потенциальным утечкам памяти Такое поведение воспроизводится на ax 3.0 sp3, sp5 с KR2 и без него, ax 4.0 без sp
__________________
Axapta v.3.0 sp5 kr2 |
|
23.03.2007, 11:08 | #2 |
Участник
|
Цитата:
Такая проверка дает ответ на вопрос "ссылается ли данная переменная на класс или нет". И ничего больше. Цитата:
Сообщение от AndyD
В принципе , такая проверка безопасна, она не позволит обратиться к методам такого класса.Но, пока dictTable (в принципе, это касается всего семейства классов Dict*) находится в области видимости, объект остается в памяти.
По-моему, это ведет к потенциальным утечкам памяти Такое поведение воспроизводится на ax 3.0 sp3, sp5 с KR2 и без него, ax 4.0 без sp См доку по java и форумы по java См. также: http://forum.mazzy.ru/index.php?showtopic=310 и Что передается функциям, ссылки или значения? |
|
23.03.2007, 11:14 | #3 |
Участник
|
Цитата:
Да и общий посыл не об этом.
__________________
Axapta v.3.0 sp5 kr2 |
|
23.03.2007, 11:28 | #4 |
Участник
|
Цитата:
0. Объект не создан 1. Была произведена попытка создать объект. (В памяти было выделено место под него) 2. Но из-за неправильных данных new не закончил создание объекта. 3. показывается, что в памяти не освобождено место. Поскольку сборщик мусора не отработал. 4. присваивание NULL не только освобождает ссылку, но еще и запускает сборщик мусора. В общем, не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java... |
|
23.03.2007, 11:34 | #5 |
Участник
|
А как тогда интерпретировать это?
X++: static void JobXXXX(Args _args) { DictTable dictTable; DictTable dictTable2; HeapCheck hc = new HeapCheck(); ; info (strfmt("Кол-во объектов в памяти до создания %1", hc.countObjects(classnum(DictTable)))); dictTable = new DictTable(0); if (dictTable == null) info("Проверка на NULL вернула истину"); info (strfmt("Кол-во объектов в памяти после создания %1", hc.countObjects(classnum(DictTable)))); hc.firstUnfreedObject(); while (hc.moreUnfreedObjects()) { if (hc.unfreedObjectClass() == classStr(DictTable)) { info(strfmt("Кол-во ссылок на класс %1", hc.unfreedObjectUseCount())); } hc.nextUnfreedObject(); } dictTable2 = dictTable; hc.firstUnfreedObject(); while (hc.moreUnfreedObjects()) { if (hc.unfreedObjectClass() == classStr(DictTable)) { info(strfmt("Кол-во ссылок на класс %1", hc.unfreedObjectUseCount())); } hc.nextUnfreedObject(); } dictTable = null; info (strfmt("Кол-во объектов в памяти после присвоения NULL %1", hc.countObjects(classnum(DictTable)))); dictTable2 = null; info (strfmt("Кол-во объектов в памяти после присвоения NULL %1", hc.countObjects(classnum(DictTable)))); }
__________________
Axapta v.3.0 sp5 kr2 |
|
23.03.2007, 11:46 | #6 |
Участник
|
На сайте Эхо Москвы есть передача Суть событий
В заставке Сергей Пархоменко говорит: "Я обещал вам объяснить суть событий? Объясняю. По пятницам после 9 вечера"... Объясняю: Все зависит от реализации java-машины. ((dictTable == null) == true) вовсе не означает, что dictTable физически содержит 0. Такая проверка дает ответ на вопрос "ссылается ли данная переменная на класс или нет". И ничего больше. Причем уточняю: "на экземпляр (instance) класса". В данном случае обе переменные dictTable и dictTable не ссылаются на какой-то конкретный экземпляр. Но реализация может быть такова, что они физически все же ссылаются в какое-то место памяти. И еще раз напомню: не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java... Это Java, а не С |
|
23.03.2007, 13:23 | #7 |
Участник
|
Цитата:
Сообщение от mazzy
В данном случае обе переменные dictTable и dictTable не ссылаются на какой-то конкретный экземпляр. Но реализация может быть такова, что они физически все же ссылаются в какое-то место памяти.
И еще раз напомню: не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java... Это Java, а не С Кстати, ни одни сборщик мусора не удалит объект в памяти, на который есть ссылки. Ради эксперимента вставил в класс Info код по созданию "пустого" DictTable и добавил метод по его удалению (явному присвоению NULL). После рестарта ссылка на объект оставлась до тех пор, пока не вызвал метод по удалению В общем, как такой объект ни называй, память он занимает, пока явно не будет присвоен null или не выйдет из области видимости
__________________
Axapta v.3.0 sp5 kr2 |
|
23.03.2007, 13:40 | #8 |
Участник
|
Цитата:
объект в java занимает память пока не будет вызван его деструктор. Да, в java есть деструкторы. Просто конкретная реализация под названием X++ не позволяет вызвать деструктор явно (или я не знаю такого способа). В java деструкторы вызываются в основном сборщиком мусора. Вручную деструкторы вызываются очень редко (как раз в подобных случаях, когда конструктору не удалось создать объект) Чтобы заглубляться в вопрос дальше, лучше рыть в сторону java-документации и java-форумов. |
|
23.03.2007, 11:50 | #9 |
Участник
|
Ситуация следующая:
X++: static void Job27(Args _args) { DictTable pseudoNull = new DictTable(0); DictTable pseudoNull2 = new DictTable(0); DictTable trueNull = null; DictTable trueNull2 = null; #localmacro.test info('%1 --> '+((%1)?'true':'false')); #endmacro ; #test(pseudoNull == null) #test(pseudoNull == pseudoNull2) #test(pseudoNull2 == trueNull) #test(trueNull == trueNull2) } pseudoNull == null --> true pseudoNull == pseudoNull2 --> false pseudoNull2 == trueNull --> false trueNull == trueNull2 --> true Вывод в аксапте существуют "пустые объекты". Эти обхекты существуют и занимают память, они разные. Но ==null компилируется как "x==null || is_empty(x)", где is_empty некоторая функция проверки на пустоту. |
|
23.03.2007, 11:50 | #10 |
Участник
|
Кстати, поиск по ключевому слову HeadCheck по этому форуму дает интересные результаты.
|
|
23.03.2007, 11:52 | #11 |
Участник
|
легко видеть что
x==null не эквивалентно y=null x==y; |
|
23.03.2007, 13:58 | #12 |
Участник
|
Явный вызов деструктора Object.finalize();
В отличие от java в Axapta деструктор можно вызвать только явно.
__________________
Axapta v.3.0 sp5 kr2 |
|
23.03.2007, 14:17 | #13 |
Участник
|
Цитата:
Object.finalize() выдает runtime-ошибку. |
|
23.03.2007, 14:45 | #14 |
Участник
|
Упс.
Этот метод должен быть перекрыт для класса. И тоже не удаляет объект из памяти - счетчик ссылок не сбрасывается до явного присвоения NULL экземпляру.
__________________
Axapta v.3.0 sp5 kr2 |
|
23.03.2007, 14:49 | #15 |
Участник
|
Ну, насколько я помню из DevGuide, этот метод и не должен удалять объект из памяти. Вызов этого метода сигнализирует сборщику, что объект можно очищать. А вот когда он его очистит, это уже ХЗ
|
|
23.03.2007, 14:52 | #16 |
Участник
|
Как перекрыт?
В Аксапте у Object нет метода finalize(). В том то и проблема, IMHO. Не смог удержаться http://www.artlebedev.ru/tools/technogrette/js/likbez/ |
|
23.03.2007, 15:03 | #17 |
Участник
|
Цитата:
А вот перекрыть у любого класса можно как минимум 2 метода - new и finalize() Опять же, по-моему об этом даже где-то в DevGuide написано, что мол, в метод этот помещать нужно необходимые очистки использованных в процессе работы класса объектов. |
|
23.03.2007, 15:07 | #18 |
Участник
|
Я тормоз. Извините.
А у Object этого метода нет? Или есть, а я торможу? |
|
23.03.2007, 15:17 | #19 |
Участник
|
У Object, кажется, нет. Во всяком случае нижеприведенный код вызывает ошибку времени выполнения на последней строке.
Class1 - "пустой" класс. Никаких методов не перекрывал. X++: static void Job41(Args _args) { object j = new Object(); Class1 cl = new Class1(); ; cl.finalize(); j.finalize(); } |
|
23.03.2007, 15:15 | #20 |
Участник
|
У Object'а он тоже есть. Не виден в IntelliSense
2 kashperuk Я тоже так думал, пока не стал проверять. Результат - вся предыдущая дискуссия
__________________
Axapta v.3.0 sp5 kr2 |
|
Теги |
ax3.0, ax4.0 |
|
|