0 / 0 / 0
Регистрация: 31.08.2013
Сообщений: 19
1

Как вернуть OS освобожденную программой память?

31.08.2013, 06:22. Показов 1575. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В какой-то момент времени моя программа динамически размещает в памяти большой объем данных ~5 Гб с помощью оператора allocate. Спустя несколько минут она освобождает память оператором deallocate. Однако OS по-прежнему считает, что моя программа занимает эти 5 Гб памяти. Что надо сделать, чтобы OS увидела освобождение памяти?
Язык: Fortran90
IDE: Eclipse Kepler
OS: RedHat 6
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.08.2013, 06:22
Ответы с готовыми решениями:

Как вернуть OS освобожденную программой память? - дубль темы из раздела Fortran
В какой-то момент времени моя программа динамически размещает в памяти большой объем данных ~5 Гб с...

Как вернуть память wi-fi роутера, как вернуть родную прошивку
Здравствуйте подскажите мне пожалуйста! у меня имеется N ADSL2+ Modem Router Netis DL4323U с...

Как освободить память занимаемую вектором и явно вернуть системе?
Здравствуйте! Вопрос: Как освободить память занимаемую вектором и явно вернуть системе?

Можно ли вернуть значение программой?
Есть задание сделать консольную программку и там такая строчка: "В случае успеха программа...

10
21 / 19 / 4
Регистрация: 26.08.2013
Сообщений: 172
02.09.2013, 15:37 2
Покажите код, то место где используются операторы allocate и deallocate. Вообще оператор deallocate освобождает выделенную память.

Добавлено через 4 часа 1 минуту
Попробуйте модернизировать код такими атрибутами. Переменная DeAllocateStatus покажет действительно ли утечка памяти в этой программной единице или где-то еще.
Fortran
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
implicit none
integer :: AllocateStatus, DeAllocateStatus
!-----------------------
allocate(test_array(N), stat = AllocateStatus)
if (AllocateStatus /= 0)
write(*,*) 'Not enough memory'
stop 
end if
!------------------
deallocate(test_array, stat = DeAllocateStatus)
if (DeallocateStatus == 0) then 
write(*,*) 'Deallocate successful' 
else
write(*,*) 'Memory leak' 
end if
0
0 / 0 / 0
Регистрация: 31.08.2013
Сообщений: 19
04.09.2013, 05:45  [ТС] 3
Я организую данные в виде дерева:
Fortran
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
type Child
    type(Point), pointer :: ref
end type Child
 
type Point
    !...
        !Собственно данные этого узла
    !...
    integer(1) :: index !номер набора данных, к которому относится этот узел
        integer(1), dimension(-1:1,-1:1,-1:1) :: children_exist
        type(Child), allocatable, dimension( :,:,: ) :: children !ссылки на узлы следующего уровня дерева
end type Point
 
Для удаления узлов дерева я использую рекурсивную процедуру:
 
recursive subroutine delete_elements(node,exist_node,index)!удаляет элементы типа index, удаляем элемент только при отсутствии потомков
    use global_var
    implicit none
    integer :: index
    type(Point), pointer :: node
    integer(1) :: exist_node
    integer :: l,p,m
    do l=-1,1
        do p=-1,1
            do m=-1,1
                if (node%children_exist(l,p,m)==1) &
                    &call delete_elements(node%children(l,p,m)%ref,node%children_exist(l,p,m),index)
            end do
        end do
    end do
    if (all(node%children_exist==0) .and. allocated(node%children)) deallocate(node%children)
    if (all(node%children_exist==0) .and. node%index==index) then
        deallocate(node)
        nullify(node)
        exist_node=0
    else if (node%index==index) then
        node%index=0
    end if
end subroutine delete_elements
Далее, я создаю последовательно три набора данных M(index=1), N(index=2), L(index=3). Данные всех наборов являются узлами одного дерева. Если я вызываю процедуру
call delete_elements(...,3),
то удаляется последний созданный в памяти набор данных, и остаются наборы M и N. В этом случае память освобождается, т.е. System Monitor показывает уменьшение размеров программы в памяти. Если я вызываю процедуру
call delete_elements(...,2),
то удаляется предпоследний созданный в памяти набор данных, и остаются наборы M и L . Но в этом случае размер программы, согласно System Monitor, не меняется. Вопрос - почему?
0
21 / 19 / 4
Регистрация: 26.08.2013
Сообщений: 172
04.09.2013, 18:11 4
Спс, что отключили смайлики. Оформляйте пожалуйста листинги с соответствующих тегах.

Как было предложено выше добавьте соответствующие атрибуты в deallocate и выведите их на печать где-нибудь чтобы увидеть когда действительно происходит освобождение памяти.

ЗЫ: имхо лучше наименовать условия и циклы когда их много или они вложенные и не ленится дописывать end if.
0
0 / 0 / 0
Регистрация: 31.08.2013
Сообщений: 19
04.09.2013, 19:04  [ТС] 5
Благодарю. Переменную DeAllocateStatus я добавил во все операторы deallocate сразу после вашего поста. Ситуации DeAllocateStatus/=0 не возникает.

Fortran
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
type Child
    type(Point), pointer :: ref
end type Child
 
type Point
    ...
    Собственно данные этого узла
    ...
    integer(1) :: index !номер набора данных, к которому относится этот узел
    integer(1), dimension(-1:1,-1:1,-1:1) :: children_exist
    type(Child), allocatable, dimension( :,:,: ) :: children !ссылки на узлы следующего уровня дерева
end type Point
 
recursive subroutine delete_elements(node,exist_node,index)!удаляет элементы типа index, удаляем элемент только при отсутствии потомков
    use global_var
    implicit none
    integer :: index
    type(Point), pointer :: node
    integer(1) :: exist_node
    integer :: l,p,m
    do l=-1,1
        do p=-1,1
            do m=-1,1
                if (node%children_exist(l,p,m)==1) &
                &call delete_elements(node%children(l,p,m)%ref,node%children_exist (l,p,m),index)
            end do
        end do
    end do
    if (all(node%children_exist==0) .and. allocated(node%children)) deallocate(node%children)
    if (all(node%children_exist==0) .and. node%index==index) then
        deallocate(node)
        nullify(node)
        exist_node=0
    else if (node%index==index) then
        node%index=0
    end if
end subroutine delete_elements
0
21 / 19 / 4
Регистрация: 26.08.2013
Сообщений: 172
04.09.2013, 19:59 6
Спасибо теперь читать легче. Если deallocate работает корректно и всегда при вызове убирает выделение памяти значит проблема в условиях вызова deallocate. И условие завершения подпрограммы (мне кажется нехорошо отсутствие оператора return , особенно в рекурсивной подпрограмме).
0
0 / 0 / 0
Регистрация: 31.08.2013
Сообщений: 19
04.09.2013, 20:09  [ТС] 7
У меня такая ситуация возникает: если я удаляю данные, добавленные последними, то память возвращается в ОС, если же я удаляю данные, после введения в память которых добавлялись еще другие данные, то память в ОС не возвращается.
0
21 / 19 / 4
Регистрация: 26.08.2013
Сообщений: 172
04.09.2013, 20:49 8
Что будет если брать не 3 набора (index=1..3) , а скажем 5 (index1..5) или 2 (index =1,2). также будет освобождаться память только последнего?
0
0 / 0 / 0
Регистрация: 31.08.2013
Сообщений: 19
05.09.2013, 00:25  [ТС] 9
Да.
0
21 / 19 / 4
Регистрация: 26.08.2013
Сообщений: 172
06.09.2013, 15:39 10
Доопределил переменные и попытался откомпилировать.
У меня с моими ключами компилятор (Intel fortran 13.1.1) дает предупреждения на ifы, Рекомендую переписать с явными end if, У меня складывается ощущение, что он действительно не корректно воспринимает неявное окончание условия.

Добавлено через 7 минут
Цитата Сообщение от FixRoute Посмотреть сообщение
Доопределил переменные и попытался откомпилировать.
У меня с моими ключами компилятор (Intel fortran 13.1.1) дает предупреждения на ifы, Рекомендую переписать с явными end if, У меня складывается ощущение, что он действительно не корректно воспринимает неявное окончание условия.
ПС: Можно посмотреть, что покажет allocated(второй набор) после выполнения удаления второго из трех наборов.

ППС: Вообще в фортране95 освобождение выделенной под локальный размещаемый массив памяти происходит автоматически при выходе из процедуры.
В нашем случае это ф90 и рекурсивная процедура так что нужно внимательно посмотреть изначально правильно ли выделяется память и что дальше с ней происходит.
0
0 / 0 / 0
Регистрация: 31.08.2013
Сообщений: 19
06.09.2013, 21:12  [ТС] 11
Цитата Сообщение от FixRoute Посмотреть сообщение
В нашем случае это ф90 и рекурсивная процедура так что нужно внимательно посмотреть изначально правильно ли выделяется память и что дальше с ней происходит.
Скажите, пожалуйста, как это можно посмотреть?

Добавлено через 9 минут
Может быть, есть какая-то программа для этого?
0
06.09.2013, 21:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.09.2013, 21:12
Помогаю со студенческими работами здесь

Память занимаемая программой
Здравствуйте. Возникла надобность в исследовании затрат ОЗУ на мою программу. Программа простая: 1...

вернуть память флешке
Есть флешка для сотика. 4гб. Когда перепрошивал кпк нужно было создать какието разделы. Теперь...

SaveDialog: вернуть память после выполнения
как сделать чтоб SaveDialog вернул мне память после выполненияSaveDialo->Execute(); вот как я...

После замены озу не включается компьютер ( плата не издаёт звук) даже если вернуть старую память
Материнская плата asus p5kc. Можно подключить либо ддр2 либо ддр3, стояло 2 по 1гб ддр2. Купил 2...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru