Fortran освобождает массив, но не выпущен в ОС

У меня следующий вопрос: как освободить память массива в типе? Как% b% c, как мне освободить c? конкретная проблема (среда компилятора, которую я пробовал, - это версия gfortran gcc4.4.7 и версия ifort 18.0.1.OS: linux):

 module grist_domain_types

     implicit none

     public :: aaa 

      type bbb 
         real (8), allocatable   :: c(:)
      end type bbb 

      type aaa 
         type(bbb),  allocatable :: b(:) 
      end type aaa 

 end module grist_domain_types

 program main

    use grist_domain_types
    type(aaa) :: a
    integer(4) :: time,i
    time=20

    allocate(a%b(1:100000000))
    call sleep(time)!--------------1

    do i=1,100000000
        allocate(a%b(i)%c(1:1))
    enddo
    call sleep(time)!--------------2

    do i=1,100000000
        deallocate(a%b(i)%c)
    enddo
    call sleep(time)!--------------3

    deallocate(a%b)
    call sleep(time)!--------------4


 end program

Сначала "gfortran main.F90 -o main" скомпилируйте программу и запустите эту программу. Затем я использую top -p processID, чтобы увидеть память. Когда программа выполняется до 1, объем памяти составляет 4,5 ГБ. Когда программа выполняется до 2, объем памяти составляет 7,5 ГБ. Когда программа выполняется до 3, память также составляет 7,5 ГБ (но я думаю, что это 4,5 ГБ). Когда программа выполняется до 4, память 3G (я думаю, 0G или близко к 0G). Итак, освобождение (a% b (i)% c), похоже, не работает. Однако я использую valgrind, чтобы увидеть память. память этой программы полностью освобождена ... Я использовал ifort и gfortran. Эта проблема возникает независимо от того, какой компилятор я использую. Как объяснить этот вопрос? Я выделяю много массивов c таким образом, программа окончательно выйдет из строя из-за нехватки памяти. И как это решить?

В вашем тесте вы выделили память, но не использовали ее. Обычно (для массива) выделение резервирует память, но не может применяться к физической памяти. Я бы добавил операторы записи на каждом этапе, а также включил инициализацию c в цикл.

johncampbell 09.07.2018 06:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
350
2

Ответы 2

Взгляните на эта почта с форума Intel. Там есть 2 важные сведения:

  1. (От доктора Форрана):

    When you do a DEALLOCATE, the memory that was allocated returns to the pool used by the memory allocator (on Linux and OS X this is the same as C's malloc/free). The memory is not released back to the OS - it is very rare that this would even be possible. What often happens is that the pattern of allocations and deallocations causes virtual memory to be fragmented, so that while the total available space may be high, there may not be sufficient contiguous space to allocate a large item. Unlike with disks, there is no way to "defrag" memory.

  2. (От Джима Демпси)

    See if you can deallocate the memory in the reverse order in which it was allocated. This can reduce memory fragmentation.

Вы также можете обратиться к сообщению Intel этот другой:

During the program run, the Fortran runtime library will manage your heap. Yes, if data is DEALLOCATED, the runtime may choose to wait to release that memory. It's an optimization - if you do another ALLOCATE with the same size it will just reuse those pages. If the heap starts to run low, it will do some collection but not until it's absolutely necessary.

Кроме того, позвольте мне добавить кое-что: проверьте, нет ли других объектов, динамически создаваемых в области видимости, таких как автоматические массивы или копии временных массивов. Это может потребовать памяти, которая может быть освобождена только тогда, когда они выйдут из области видимости.

Подводя итоги, даже если "top" говорит, что память все еще используется, беспокоиться следует только в том случае, если ваша программа начинает давать сбой или если Valgrind показывает что-то ужасное.

Я видел проблему, которую они обсуждали. Это очень похоже на то, что я встречал. Может, они просто сказали причину. Не предложил решения. Так что я до сих пор не знаю, как это решить.

L.Chao 09.07.2018 07:10

Дело в том, что, может быть, у вас нет проблем. У вас закончилась память? Память может быть недоступна для появляться, но если она была освобождена (помечена как свободная), но не освобождена, и программа запрашивает дополнительные выделения, эту память можно использовать повторно. Вы можете сделать другое распределение (после освобождения) и проверить, увеличилось ли использование памяти или было ли повторно использовано то же количество.

Rodrigo Rodrigues 09.07.2018 07:20

да, как вы догадались. проблема не в памяти. Мне нужно выделить таким образом много c-массивов? Он был освобожден, но не выпущен. Мне нужно, чтобы он был освобожден полностью. Я хочу, чтобы он был выпущен как обычный массив.

L.Chao 09.07.2018 07:45

В итоге программа выйдет из строя из-за нехватки памяти.

L.Chao 09.07.2018 07:52

@ L.Chao В этом случае предоставьте сбой MCVE, а не суррогат.

Vladimir F 10.07.2018 11:10

Я изменил вашу программу (чтобы посмотреть, где она была) и запустил Windows 7 / gFortran 7.2.0. Он не демонстрирует сохранение памяти, когда вы сообщаете, поскольку объем памяти возвращается к 13 МБ. Вопреки моему комментарию, потребность в памяти не изменилась во время инициализации c.

   module grist_domain_types

     implicit none

     public :: aaa 

      type bbb 
         real (8), allocatable   :: c(:)
      end type bbb 

      type aaa 
         type(bbb),  allocatable :: b(:) 
      end type aaa 

   end module grist_domain_types

   program main

    use grist_domain_types
    type(aaa)  :: a
    integer(4),parameter :: million = 1000000
    integer(4) :: n = 100*million
    integer(4) :: time = 5, i, pass

  do pass = 1,5
    write (*,*) ' go #', pass

    allocate(a%b(1:n))
    write (*,*) 'allocate b'
    call sleep(time)!--------------1
    write (*,*) ' go'

    do i=1,n
        allocate(a%b(i)%c(1:1))
    enddo
    write (*,*) 'allocate c'
    call sleep(time)!--------------2
    write (*,*) ' go'

    do i=1,n
        a%b(i)%c = real(i)
    enddo
    write (*,*) 'use c'
    call sleep(time)!--------------2a
    write (*,*) ' go'

    do i=1,n
        deallocate(a%b(i)%c)
    enddo
    write (*,*) 'deallocate c'
    call sleep(time)!--------------3
    write (*,*) ' go'

    deallocate(a%b)
    write (*,*) 'deallocate b'
    call sleep(time)!--------------4
  end do

    write (*,*) ' done : exit ?'
    read (*,*) i

   end program

edit: Я повторил тест с помощью do pass ... чтобы повторить требования к памяти. Это показывает отсутствие утечки памяти для этой программы Fortran. Я использую диспетчер задач для определения использования памяти как для этой программы, так и для операционной системы. Ваш конкретный компилятор O / S и Fortran может отличаться.

Я тоже не знаю, я просто новичок. Может быть, причина в том, что используемая вами версия компилятора отличается от моей.

L.Chao 09.07.2018 08:08

Другие вопросы по теме