|  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, 11:50 | #7 | 
| Участник | 
			
			Ситуация следующая: 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 | #8 | 
| Участник | 
			
			Кстати, поиск по ключевому слову HeadCheck по этому форуму дает интересные результаты.
		 | 
|  | 
|  23.03.2007, 11:52 | #9 | 
| Участник | 
			
			легко видеть что  x==null не эквивалентно y=null x==y; | 
|  | 
|  23.03.2007, 13:23 | #10 | 
| Участник | Цитата: 
		
			Сообщение от mazzy
			   В данном случае обе переменные dictTable и dictTable не ссылаются на какой-то конкретный экземпляр. Но реализация может быть такова, что они физически все же ссылаются в какое-то место памяти. И еще раз напомню: не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java... Это Java, а не С  Кстати, ни одни сборщик мусора не удалит объект в памяти, на который есть ссылки. Ради эксперимента вставил в класс Info код по созданию "пустого" DictTable и добавил метод по его удалению (явному присвоению NULL). После рестарта ссылка на объект оставлась до тех пор, пока не вызвал метод по удалению В общем, как такой объект ни называй, память он занимает, пока явно не будет присвоен null или не выйдет из области видимости 
				__________________ Axapta v.3.0 sp5 kr2 | 
|  | 
|  23.03.2007, 13:40 | #11 | 
| Участник | Цитата: объект в java занимает память пока не будет вызван его деструктор. Да, в java есть деструкторы. Просто конкретная реализация под названием X++ не позволяет вызвать деструктор явно (или я не знаю такого способа). В java деструкторы вызываются в основном сборщиком мусора. Вручную деструкторы вызываются очень редко (как раз в подобных случаях, когда конструктору не удалось создать объект) Чтобы заглубляться в вопрос дальше, лучше рыть в сторону java-документации и java-форумов. | 
|  | 
|  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:15 | #19 | 
| Участник | 
			
			У Object'а он тоже есть. Не виден в IntelliSense 2 kashperuk Я тоже так думал, пока не стал проверять. Результат - вся предыдущая дискуссия 
				__________________ Axapta v.3.0 sp5 kr2 | 
|  | 
|  23.03.2007, 15:17 | #20 | 
| Участник | 
			
			У Object, кажется, нет. Во всяком случае нижеприведенный код вызывает ошибку времени выполнения на последней строке. Class1 - "пустой" класс. Никаких методов не перекрывал. X++: static void Job41(Args _args) { object j = new Object(); Class1 cl = new Class1(); ; cl.finalize(); j.finalize(); } | 
|  | 
| Теги | 
| ax3.0, ax4.0 | 
|  | 
| 
 |