| 
			
			 | 
		#1 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
			
			 
			
			Предлагаю вниманию такой код 
		
		
		
		
		
		
			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  | 
| 
	
 | 
| 
			
			 | 
		#2 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
Такая проверка дает ответ на вопрос "ссылается ли данная переменная на класс или нет". И ничего больше. Цитата: 
	
		
			Сообщение от AndyD
			 
 
			В принципе , такая проверка безопасна, она не позволит обратиться к методам такого класса.Но, пока dictTable (в принципе, это касается всего семейства классов Dict*) находится в области видимости, объект остается в памяти.  
		
	По-моему, это ведет к потенциальным утечкам памяти Такое поведение воспроизводится на ax 3.0 sp3, sp5 с KR2 и без него, ax 4.0 без sp ![]() См доку по java и форумы по java См. также: http://forum.mazzy.ru/index.php?showtopic=310 и Что передается функциям, ссылки или значения?  | 
| 
	
 | 
| 
			
			 | 
		#3 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
Да и общий посыл не об этом. 
				__________________ 
		
		
		
		
	Axapta v.3.0 sp5 kr2  | 
| 
	
 | 
| 
			
			 | 
		#4 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
0. Объект не создан 1. Была произведена попытка создать объект. (В памяти было выделено место под него) 2. Но из-за неправильных данных new не закончил создание объекта. 3. показывается, что в памяти не освобождено место. Поскольку сборщик мусора не отработал. 4. присваивание NULL не только освобождает ссылку, но еще и запускает сборщик мусора. В общем, не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java...  | 
| 
	
 | 
| 
			
			 | 
		#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  | 
| 
	
 | 
| 
			
			 | 
		#6 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			На сайте Эхо Москвы есть передача Суть событий 
		
		
		
		
		
		
			
		
		
		
		
	В заставке Сергей Пархоменко говорит: "Я обещал вам объяснить суть событий? Объясняю. По пятницам после 9 вечера"... Объясняю: Все зависит от реализации java-машины. ((dictTable == null) == true) вовсе не означает, что dictTable физически содержит 0. Такая проверка дает ответ на вопрос "ссылается ли данная переменная на класс или нет". И ничего больше. Причем уточняю: "на экземпляр (instance) класса". В данном случае обе переменные dictTable и dictTable не ссылаются на какой-то конкретный экземпляр. Но реализация может быть такова, что они физически все же ссылаются в какое-то место памяти. И еще раз напомню: не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java... Это Java, а не С  
		 | 
| 
	
 | 
| 
			
			 | 
		#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 некоторая функция проверки на пустоту.  | 
| 
	
 | 
| 
			
			 | 
		#8 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Кстати, поиск по ключевому слову HeadCheck по этому форуму дает интересные результаты.
		 
		
		
		
		
		
		
			
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#9 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			легко видеть что  
		
		
		
		
		
		
		
	x==null не эквивалентно y=null x==y;  | 
| 
	
 | 
| 
			
			 | 
		#10 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Сообщение от mazzy
			 
 
			В данном случае обе переменные dictTable и dictTable не ссылаются на какой-то конкретный экземпляр. Но реализация может быть такова, что они физически все же ссылаются в какое-то место памяти. 
		
	И еще раз напомню: не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java... Это Java, а не С ![]() Кстати, ни одни сборщик мусора не удалит объект в памяти, на который есть ссылки. Ради эксперимента вставил в класс Info код по созданию "пустого" DictTable и добавил метод по его удалению (явному присвоению NULL). После рестарта ссылка на объект оставлась до тех пор, пока не вызвал метод по удалению В общем, как такой объект ни называй, память он занимает, пока явно не будет присвоен null или не выйдет из области видимости 
				__________________ 
		
		
		
		
	Axapta v.3.0 sp5 kr2  | 
| 
	
 | 
| 
			
			 | 
		#11 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
объект в java занимает память пока не будет вызван его деструктор. Да, в java есть деструкторы. Просто конкретная реализация под названием X++ не позволяет вызвать деструктор явно (или я не знаю такого способа). В java деструкторы вызываются в основном сборщиком мусора. Вручную деструкторы вызываются очень редко (как раз в подобных случаях, когда конструктору не удалось создать объект) Чтобы заглубляться в вопрос дальше, лучше рыть в сторону java-документации и java-форумов.  | 
| 
	
 | 
| 
			
			 | 
		#12 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Явный вызов деструктора Object.finalize(); 
		
		
		
		
		
		
			В отличие от java в Axapta деструктор можно вызвать только явно. 
				__________________ 
		
		
		
		
	Axapta v.3.0 sp5 kr2  | 
| 
	
 | 
| 
			
			 | 
		#13 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
Object.finalize() выдает runtime-ошибку.  | 
| 
	
 | 
| 
			
			 | 
		#14 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Упс. 
		
		
		
		
		
		
			Этот метод должен быть перекрыт для класса. И тоже не удаляет объект из памяти - счетчик ссылок не сбрасывается до явного присвоения NULL экземпляру. 
				__________________ 
		
		
		
		
	Axapta v.3.0 sp5 kr2  | 
| 
	
 | 
| 
			
			 | 
		#15 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Ну, насколько я помню из DevGuide, этот метод и не должен удалять объект из памяти. Вызов этого метода сигнализирует сборщику, что объект можно очищать. А вот когда он его очистит, это уже ХЗ
		 
		
		
		
		
		
		
			
		
		
		
		
	 | 
| 
	
 | 
| 
			
			 | 
		#16 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Как перекрыт? 
		
		
		
		
		
		
			
		
		
		
		
	В Аксапте у Object нет метода finalize(). В том то и проблема, IMHO. Не смог удержаться http://www.artlebedev.ru/tools/technogrette/js/likbez/  | 
| 
	
 | 
| 
			
			 | 
		#17 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
А вот перекрыть у любого класса можно как минимум 2 метода - new и finalize() Опять же, по-моему об этом даже где-то в DevGuide написано, что мол, в метод этот помещать нужно необходимые очистки использованных в процессе работы класса объектов.  | 
| 
	
 | 
| 
			
			 | 
		#18 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Я тормоз. Извините. 
		
		
		
		
		
		
			
		
		
		
		
	А у Object этого метода нет? Или есть, а я торможу?  | 
| 
	
 | 
| 
			
			 | 
		#19 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			У Object'а он тоже есть. Не виден в IntelliSense 
		
		
		
		
		
		
			2 kashperuk Я тоже так думал, пока не стал проверять. Результат - вся предыдущая дискуссия 
				__________________ 
		
		
		
		
	Axapta v.3.0 sp5 kr2  | 
| 
	
 | 
| 
			
			 | 
		#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 | 
| 
	
	 | 
	
		
		
  |