AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 23.03.2007, 10:58   #1  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
! Создание экземпляра класса 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))));
}
Получается, что проверка на NULL для класса не дает ответа - создался он или нет.
В принципе , такая проверка безопасна, она не позволит обратиться к методам такого класса.Но, пока dictTable (в принципе, это касается всего семейства классов Dict*) находится в области видимости, объект остается в памяти.
По-моему, это ведет к потенциальным утечкам памяти

Такое поведение воспроизводится на ax 3.0 sp3, sp5 с KR2 и без него, ax 4.0 без sp
__________________
Axapta v.3.0 sp5 kr2
Старый 23.03.2007, 11:08   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от AndyD Посмотреть сообщение
Получается, что проверка на NULL для класса не дает ответа - создался он или нет.
Конечно нет.
Такая проверка дает ответ на вопрос "ссылается ли данная переменная на класс или нет". И ничего больше.

Цитата:
Сообщение от AndyD Посмотреть сообщение
В принципе , такая проверка безопасна, она не позволит обратиться к методам такого класса.Но, пока dictTable (в принципе, это касается всего семейства классов Dict*) находится в области видимости, объект остается в памяти.
По-моему, это ведет к потенциальным утечкам памяти

Такое поведение воспроизводится на ax 3.0 sp3, sp5 с KR2 и без него, ax 4.0 без sp
Такое поведение воспроизводится во всех java-машинах
См доку по java и форумы по java

См. также: http://forum.mazzy.ru/index.php?showtopic=310
и Что передается функциям, ссылки или значения?
__________________
полезное на axForum, github, vk, coub.
Старый 23.03.2007, 11:14   #3  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Сообщение от mazzy Посмотреть сообщение
Конечно нет.
Такая проверка дает ответ на вопрос "ссылается ли данная переменная на класс или нет". И ничего больше.
Э нет. Как раз таки в приведенном мной коде переменная ссылается на объект в памяти. Хотя ее проверка и говорит об обратном (!dictTable дает точно такой же результат).
Да и общий посыл не об этом.
__________________
Axapta v.3.0 sp5 kr2
Старый 23.03.2007, 11:28   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от AndyD Посмотреть сообщение
Как раз таки в приведенном мной коде переменная ссылается на объект в памяти. Хотя ее проверка и говорит об обратном (!dictTable дает точно такой же результат).
Да и общий посыл не об этом.
Я правильно понимаю, что вопрос в том, как интерпретировать результаты работы данного job'а? (см. аттач)

0. Объект не создан
1. Была произведена попытка создать объект. (В памяти было выделено место под него)
2. Но из-за неправильных данных new не закончил создание объекта.
3. показывается, что в памяти не освобождено место. Поскольку сборщик мусора не отработал.
4. присваивание NULL не только освобождает ссылку, но еще и запускает сборщик мусора.

В общем, не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java...
Изображения
 
__________________
полезное на axForum, github, vk, coub.
Старый 23.03.2007, 11:34   #5  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
А как тогда интерпретировать это?
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  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от AndyD Посмотреть сообщение
А как тогда интерпретировать это?
На сайте Эхо Москвы есть передача Суть событий
В заставке Сергей Пархоменко говорит: "Я обещал вам объяснить суть событий? Объясняю. По пятницам после 9 вечера"...

Объясняю:
Все зависит от реализации java-машины.
((dictTable == null) == true) вовсе не означает, что dictTable физически содержит 0.
Такая проверка дает ответ на вопрос "ссылается ли данная переменная на класс или нет". И ничего больше.
Причем уточняю: "на экземпляр (instance) класса".

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

И еще раз напомню: не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java...

Это Java, а не С
__________________
полезное на axForum, github, vk, coub.
Старый 23.03.2007, 11:50   #7  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Ситуация следующая:
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  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Кстати, поиск по ключевому слову HeadCheck по этому форуму дает интересные результаты.
__________________
полезное на axForum, github, vk, coub.
Старый 23.03.2007, 11:52   #9  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
легко видеть что

x==null

не эквивалентно

y=null

x==y;
Старый 23.03.2007, 13:23   #10  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Цитата:
Сообщение от mazzy Посмотреть сообщение
В данном случае обе переменные dictTable и dictTable не ссылаются на какой-то конкретный экземпляр. Но реализация может быть такова, что они физически все же ссылаются в какое-то место памяти.

И еще раз напомню: не забывай о том, что память в java-машинах освобождается не сразу, а только после работы сборщика мусора. См. ФАКи по java...

Это Java, а не С
Однако ObjectIdent отлично проглатывает такой "псевдоэкземпляр", в отличие от NULL и при его получении происходит увеличение счетчика ссылок на единицу.
Кстати, ни одни сборщик мусора не удалит объект в памяти, на который есть ссылки.

Ради эксперимента вставил в класс Info код по созданию "пустого" DictTable и добавил метод по его удалению (явному присвоению NULL). После рестарта ссылка на объект оставлась до тех пор, пока не вызвал метод по удалению

В общем, как такой объект ни называй, память он занимает, пока явно не будет присвоен null или не выйдет из области видимости
__________________
Axapta v.3.0 sp5 kr2
Старый 23.03.2007, 13:40   #11  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от AndyD Посмотреть сообщение
В общем, как такой объект ни называй, память он занимает, пока явно не будет присвоен null или не выйдет из области видимости
Чтобы можно было ориентироваться в первоисточнике (в java), рискну уточнить:
объект в java занимает память пока не будет вызван его деструктор.

Да, в java есть деструкторы. Просто конкретная реализация под названием X++ не позволяет вызвать деструктор явно (или я не знаю такого способа). В java деструкторы вызываются в основном сборщиком мусора. Вручную деструкторы вызываются очень редко (как раз в подобных случаях, когда конструктору не удалось создать объект)

Чтобы заглубляться в вопрос дальше, лучше рыть в сторону java-документации и java-форумов.
__________________
полезное на axForum, github, vk, coub.
Старый 23.03.2007, 13:58   #12  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Явный вызов деструктора Object.finalize();
В отличие от java в Axapta деструктор можно вызвать только явно.
__________________
Axapta v.3.0 sp5 kr2
Старый 23.03.2007, 14:17   #13  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от AndyD Посмотреть сообщение
Явный вызов деструктора Object.finalize();
В отличие от java в Axapta деструктор можно вызвать только явно.
Как?
Object.finalize() выдает runtime-ошибку.
__________________
полезное на axForum, github, vk, coub.
Старый 23.03.2007, 14:45   #14  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Упс.
Этот метод должен быть перекрыт для класса.
И тоже не удаляет объект из памяти - счетчик ссылок не сбрасывается до явного присвоения NULL экземпляру.
__________________
Axapta v.3.0 sp5 kr2
Старый 23.03.2007, 14:49   #15  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Цитата:
Сообщение от AndyD Посмотреть сообщение
Упс.
Этот метод должен быть перекрыт для класса.
И тоже не удаляет объект из памяти - счетчик ссылок не сбрасывается до явного присвоения NULL экземпляру.
Ну, насколько я помню из DevGuide, этот метод и не должен удалять объект из памяти. Вызов этого метода сигнализирует сборщику, что объект можно очищать. А вот когда он его очистит, это уже ХЗ
Старый 23.03.2007, 14:52   #16  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от AndyD Посмотреть сообщение
Этот метод должен быть перекрыт для класса.
Как перекрыт?
В Аксапте у Object нет метода finalize(). В том то и проблема, IMHO.

Не смог удержаться http://www.artlebedev.ru/tools/technogrette/js/likbez/
__________________
полезное на axForum, github, vk, coub.
Старый 23.03.2007, 15:03   #17  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Цитата:
Сообщение от mazzy Посмотреть сообщение
Как перекрыт?
В Аксапте у Object нет метода finalize(). В том то и проблема, IMHO.
Не отображается он, так это точно.
А вот перекрыть у любого класса можно как минимум 2 метода - new и finalize()

Опять же, по-моему об этом даже где-то в DevGuide написано, что мол, в метод этот помещать нужно необходимые очистки использованных в процессе работы класса объектов.
Старый 23.03.2007, 15:07   #18  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от kashperuk Посмотреть сообщение
как минимум 2 метода - new и finalize()
Я тормоз. Извините.

А у Object этого метода нет? Или есть, а я торможу?
__________________
полезное на axForum, github, vk, coub.
Старый 23.03.2007, 15:15   #19  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
У Object'а он тоже есть. Не виден в IntelliSense

2 kashperuk
Я тоже так думал, пока не стал проверять. Результат - вся предыдущая дискуссия
__________________
Axapta v.3.0 sp5 kr2
Старый 23.03.2007, 15:17   #20  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Цитата:
Сообщение от mazzy Посмотреть сообщение
А у Object этого метода нет? Или есть, а я торможу?
У Object, кажется, нет. Во всяком случае нижеприведенный код вызывает ошибку времени выполнения на последней строке.

Class1 - "пустой" класс. Никаких методов не перекрывал.

X++:
static void Job41(Args _args)
{
    object j = new Object();
    Class1 cl = new Class1();
    ;
    cl.finalize();
    j.finalize();
}
Теги
ax3.0, ax4.0

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Диалог - программное создание из класса Arahnid DAX: Программирование 4 08.10.2008 18:20
Создание номенклатуры с использ. axInventTable класса. Можно ли запретить использование шаблонов записей? Hub DAX: Программирование 2 03.09.2008 15:12
Запустить метод класса loka DAX: Программирование 2 13.03.2006 15:40
Проблема с инициализацией экземпляра объекта Jox DAX: Программирование 2 11.01.2006 12:55
Создание экземпляра COM по его CLSID Borisov Nikolai DAX: Программирование 1 02.12.2002 10:37
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 15:14.