
Dmitry
23.10.2016
08:34:47
Там про ГК пишут

Oleg
23.10.2016
08:39:42
Reason #2: structs are normally value types (though you can make them reference types if you work at it). Classes are always reference types. So, if you want a value type, choose a struct. If you want a reference type, it's easiest to go with a class.

Sergey
23.10.2016
08:39:46
Структуры живут в стеке и освобождают память (и, соответсвенно, вызываются их деструкотры) при выходе из контекста. Поэтому file структура.

Oleg
23.10.2016
08:42:22
Структуру можно и не на стеке создать, тогда по идее разницы никакой

Google

Sergey
23.10.2016
08:42:24
Иначе говоря. Структуры вообще вне компетенции ГК)

Oleg
23.10.2016
08:42:56
В компетенции, GC их сканирует на наличие указателей

Max
23.10.2016
08:45:37
GC сканирует только память выделенную в куче. А вообще это нужно чтобы не парится о закрытии и свалить всё на RAII

Dmitry
23.10.2016
08:45:41
http://forum.dlang.org/post/mailman.146.1477204596.3398.digitalmars-d@puremagic.com

Oleg
23.10.2016
08:48:47
Тут короче вся фишка в том, что D'шный File это враппер над *FILE, который приходит из ядра операционки. Просто для удобства. Если бы File был классом, то ты бы смог отнаследовать его, и не имел бы предсказуемого высвобождения из памяти. Что ессесено лишено всякого смысла.
Ибо число хендлов *FILE ОГРАНИЧЕНО!
Если бы GC не успевал высвобождать хендлы (а он и не будет успвать by design) то твоя прога бы крешилась в таких ситациях
Ну и наследовать "class" File, который держит указатель "на хз что-то лежащее в ядре" просто странно было бы.

Max
23.10.2016
09:00:35

Oleg
23.10.2016
09:02:56

Google

Oleg
23.10.2016
09:03:36
Я так понимаю что мало кто знает как работает GC, но просто скажу что он даже регистры сканирует, не то что стек.

Just
24.10.2016
00:46:26
есть кто? вопрос в том, как удалить словарь. он обьявлен локально в функции, GC.collect() в конце и присвоение переменной null не помогли

Oleg
24.10.2016
03:09:10
И покажи код)

Just
24.10.2016
03:10:03
по размеру программы в оперативке и заполнил перед обнулением словарь еще раз
class Reader{
BinaryArray!(string, Node*) nodesList;
public:
this(string dateFrom){
Node*[string] nodesListTemp;
// заполняем nodesListTemp данными с файла
//передаем его в другую функцию по ссылке
nodesListTemp = null;
writeln(nodesListTemp);
}

Oleg
24.10.2016
03:12:38
Так может он в "другой функции" остался? Что происходит если удалить у него все элементы?
Или другая это writeln чтоль
Да может просто GC виртуальную память не отдает. Попробуй несколько раз такие словари создать и уничтожать, память по идее будет на одном уровне

Just
24.10.2016
03:13:58
если удалить их через nodesListTemp.remove(key) то не помогает, я даже коментировал строчку с передачей его другой функции
несколько раз там же, можно

Oleg
24.10.2016
03:22:49
Поищи у GC функцию вроде "высвободить зарезервированную память"
Можно понизить пул и резерв
А к чему вообще такое действо?

Just
24.10.2016
03:28:33
как раз читаю об этом на хабре

Oleg
24.10.2016
03:29:00

Just
24.10.2016
03:29:30
да цель же была заменить словари на массив с бинарным поиском, но для его заполнения все равно нужно предварительно создать словарь
слишком много хранит, выходит

Google

Oleg
24.10.2016
03:31:55
GC штука мало предсказуемая, но мне кажется ты зря паришься
Врядли резерв будет сильно расти

Just
24.10.2016
03:32:42
ну он по факту растет на столько, на сколько увеличить этот словарь

Oleg
24.10.2016
03:33:03
А потом он просто его переиспользует
У тебя же в цикле память не росла

Just
24.10.2016
03:33:28
но ему не будет нужно столько памяти, вот в чем дело
после создания всех структур они просто висят в памяти и по ним делается поиск иногда

Oleg
24.10.2016
03:38:44
Если действительно критично - понижай пулл/резерв
Но может ударить по скорости

Just
24.10.2016
03:48:06

Oleg
24.10.2016
03:48:54
А мне кажется что проблемы нет, память просто всегда будет чуть выше чем нужно, но не более того
D это всетаки не JavaScript, чтобы гигабайтами память жрать

Just
24.10.2016
03:50:07
ну сейчас он ее гигибайтами и жрет. хотя я что-то не так делаю, видимо

Oleg
24.10.2016
03:50:34
Хах
Может у тебя числа в куче аллоцируются? Или массивы (или что там) слишком часто ресайзятся?
Судя по тексту я думал у тебя там мегабайт 20 оверхеда

Just
24.10.2016
03:52:02
честно говоря хз) да нет, там намного больше
ну словарь этот я создаю и потом дописываю в него

Oleg
24.10.2016
03:52:56
Больше кода можешь кинуть?
Файлом

Google

Just
24.10.2016
03:53:09
хотя он же хранит указатели на стрктуры, которые я не удаляю, может поэтому и сами указатели не удаляются?

Oleg
24.10.2016
03:53:52


Just
24.10.2016
03:54:23
рассчетно для тестового примера несколько мегабайт, может десятков, точно не 100+
class Reader{
BinaryArray!(string, Node*) nodesList;
public:
this(string dateFrom){
GC.disable();
auto F=File("nodes/"~dateFrom,"r");
// create temporary dict for parsing
Node*[string] nodesListTemp;
while(!F.eof()){
try{
//writeln(F.readTrans);
auto t=F.readTrans;
if(t.src==t.dst) continue;//ignore internal links
Node* src=new Node();
Node* dst=new Node();
//find src node or init new one
if(t.src !in nodesListTemp){
src.nodeKey=t.src;
nodesListTemp[t.src]=src;
}else{
src=nodesListTemp[t.src];
}
//find dst node or init new one
if(t.dst !in nodesListTemp){
dst.nodeKey=t.dst;
nodesListTemp[t.dst]=dst;
}else{
dst=nodesListTemp[t.dst];
}
Arc* a=src.findArc(dst);
ArcParams* ap=new ArcParams();
ap.id=t.id;
ap.amount=t.amount;
a.params~=ap;
}catch{
break;
}
}
F.close();
// create nodesList from nodesListTemp
// закоментировал создание своей структуры вообще
//nodesList.loadFromDict(nodesListTemp);
// Вот тут если заполнять словарь, то рантайм програмы увеличивается
//for(int i=0; i<2; i++){
// foreach(string key, Node* node; nodesListTemp){
// nodesListTemp[key~i.to!string] = node;
// }
//}
nodesListTemp = null;
writeln(nodesListTemp);
}
вот полностью конструктор класса этот


Oleg
24.10.2016
03:58:14
GC.disable(); huh?

Just
24.10.2016
03:59:05
ну это уже позже я пробовал, а в конце вызывал GC.collect(), без него все так же
не т.е. с этой строчкой прога 175 мб, без нее 115, она конечно влияет, но 115 все равно много

Oleg
24.10.2016
04:01:14
Ты же говорил гигабайты

Admin
ERROR: S client not available

Oleg
24.10.2016
04:01:26
Ладно, понизь пул/резерв и перепроверь

Just
24.10.2016
04:10:04

Oleg
24.10.2016
04:11:21
nodesList.loadFromDict(nodesListTemp) ссылку не хранит на nodesListTemp?
Нужно цикличные зависимости искать
Может то что ты ложишь в nodesListTemp указывает на nodesListTemp
Если не критично, сделай ArcParams не классом, а структурой
И Node тоже

Just
24.10.2016
04:16:30

Oleg
24.10.2016
04:19:21
А какой структуры здесь создается больше всего?
Какая-то нетривиальная у нас ситуация!

Google

Just
24.10.2016
04:20:21
ну конкретно сейчас создаются только Node'ы
я не совсем понял пока, как это сделать, тестирую. т.е. до какого значения понизить подбираю
./test "--DRT-gcopt=profile:1 maxPoolSize:1 initReserve:10" ну вот с такими параметрами даже немного больше прога стала

Oleg
24.10.2016
04:25:21
Значит таки что-то в коде засело

Just
24.10.2016
04:25:32
void main(string[] args){
string[string] aa;
for(int i=1000000; i>0; i--){
aa[i.to!string]=i.to!string;
}
aa = null;
//wait
writeln(111);
File p;
p.popen("sleep 10");
writeln(222);
}
вот тестовый код

Oleg
24.10.2016
04:29:36
sleep сборщик не вызывает
А с GC.collect что?

Just
24.10.2016
04:30:18
ну это только, что бы успеть посмотреть размер
вот-вот... надеюсь кто-то придет и скажет что тут не так. в таком то виде тут вроде грешить на код уже не приходится

Oleg
24.10.2016
04:35:08
А компильни через LDC/LDC2

Just
24.10.2016
04:36:24
знать бы еще как, ну сейчас загуглю

Oleg
24.10.2016
04:37:43
https://github.com/ldc-developers/ldc/releases
Работает по-сути как DMD

Just
24.10.2016
04:38:12
хм, это оказалось очень легко

Oleg
24.10.2016
04:38:16
LDC 1.1.0 beta 3 и LDC 0.17.2 разные компиляторы, оба попробуй

Just
24.10.2016
04:38:21
ничего не изменилось
ну я через пакмена поставил какой-то, сейчас посмотрю

Oleg
24.10.2016
04:39:17
Только GC.collect вставляй перед wait