Каковы различия между VirtualAlloc и HeapAlloc?

Ваш объединенный список по-прежнему является многомерным массивом. Вы можете решить свою проблему с помощью следующего кода, однако предпочтительно перенести логику создания (одномерного) массива на свой контроллер (, тогда вы можете удалить фильтр first во фрагменте )

{% for item in options.projets %}
  • {% endfor %}

    демо

    77
    задан Ajay 20 September 2014 в 11:40
    поделиться

    5 ответов

    Каждый API предназначен для разных целей. Каждый из них также требует, чтобы вы использовали правильную функцию освобождения / освобождения памяти, когда закончите с памятью.

    VirtualAlloc

    Низкоуровневый Windows API, который предоставляет множество опций, но в основном полезен для людей с достаточно конкретные ситуации. Может выделять память только (редактировать: не 4 КБ) более крупными кусками. Бывают ситуации, когда вам это нужно, но вы будете знать, когда окажетесь в одной из этих ситуаций. Один из наиболее распространенных - если вам нужно совместно использовать память напрямую с другим процессом. Не используйте его для распределения памяти общего назначения. Для освобождения используйте VirtualFree .

    HeapAlloc

    Выделяет любой объем памяти, который вы запрашиваете, но не большими кусками, чем VirtualAlloc . HeapAlloc знает, когда ему нужно вызвать VirtualAlloc , и делает это автоматически. Подобно malloc , но только для Windows и предоставляет еще пару опций. Подходит для выделения общих блоков памяти. Некоторые Windows API могут потребовать, чтобы вы использовали это для выделения памяти, которую вы им передаете, или используйте его сопутствующий HeapFree , чтобы освободить память, которую они вам возвращают.

    malloc

    C способ выделения объем памяти. Предпочитайте это, если вы пишете на C, а не на C ++, и хотите, чтобы ваш код работал, например, на компьютерах Unix, или кто-то специально говорит, что вам нужно его использовать. Не инициализирует память. Подходит для выделения общих частей памяти, например HeapAlloc . Простой API. Используйте бесплатно , чтобы освободить место. Visual C ++ ' s malloc вызывает HeapAlloc .

    new

    Способ выделения памяти в C ++. Предпочтите это, если вы пишете на C ++. Он также помещает объект или объекты в выделенную память. Используйте delete для освобождения (или delete [] для массивов). new Visual Studio вызывает HeapAlloc , а затем, возможно, инициализирует объекты, в зависимости от того, как вы это называете.

    В последних стандартах C ++ (C ++ 11 и выше), если вы необходимо вручную использовать delete , вы делаете это неправильно, и вместо этого следует использовать умный указатель , например unique_ptr . Начиная с C ++ 14, то же самое можно сказать о new (заменено такими функциями, как make_unique () ).

    79
    ответ дан 24 November 2019 в 10:56
    поделиться

    В общих чертах:

    • VirtualAlloc, HeapAlloc и т. Д. - это Windows API, которые выделяют память различных типов непосредственно из ОС. VirtualAlloc управляет страницами в системе виртуальной памяти Windows, а HeapAlloc выделяет их из определенной кучи ОС. Честно говоря, вам вряд ли когда-либо понадобится использовать любой из них.

    • malloc - это стандартная библиотечная функция C (и C ++), которая выделяет память вашему процессу. Реализации malloc обычно используют один из API-интерфейсов ОС для создания пула памяти при запуске приложения и последующего выделения из него при выполнении запросов malloc

    • new - это стандартный оператор C ++, который выделяет память, а затем соответствующим образом вызывает конструкторы. объем памяти. Он может быть реализован в терминах malloc или в терминах API ОС, и в этом случае он также обычно создает пул памяти при запуске приложения.

    7
    ответ дан 24 November 2019 в 10:56
    поделиться

    VirtualAlloc - это специализированное выделение виртуальной памяти (ВМ) ОС. Распределение в системе виртуальных машин должно производиться с гранулярностью выделения, которая (гранулярность выделения) зависит от архитектуры. Выделение в системе виртуальных машин - одна из самых основных форм распределения памяти. Выделение виртуальных машин может иметь несколько форм, память не обязательно выделяется или физически поддерживается в ОЗУ (хотя это может быть). Выделение виртуальных машин обычно представляет собой выделение специального назначения , либо из-за того, что выделение должно быть

    • очень большим,
    • необходимо совместно использовать,
    • должно быть выровнено по определенному значению ( соображения производительности) или
    • вызывающему абоненту не нужно использовать всю эту память сразу ...
    • и т. д.

    HeapAlloc - это, по сути, то, что в конечном итоге вызывают malloc и new . Он разработан, чтобы быть очень быстрым и пригодным для использования во многих различных сценариях распределения общего назначения. Это «Куча» в классическом понимании. Кучи фактически настраиваются с помощью VirtualAlloc , который используется для первоначального резервирования места для распределения из ОС. После инициализации пространства с помощью VirtualAlloc различные таблицы, списки и другие структуры данных настраиваются для поддержки и управления работой HEAP. Некоторые из этих операций представляют собой динамическое изменение размера (увеличение и уменьшение) кучи, адаптацию кучи для конкретного использования (частое выделение некоторого размера) и т. Д.

    new и malloc ] в чем-то такие же, malloc , по сути, является точным вызовом HeapAlloc (heap-id-default) ; Однако new может [дополнительно] настроить выделенную память для объектов C ++ . Для данного объекта C ++ будет хранить vtables в куче для каждого вызывающего. Эти vtables являются перенаправлениями для выполнения и являются частью того, что придает C ++ его объектно-ориентированные характеристики, такие как наследование, перегрузка функций и т. Д.

    Некоторые другие общие методы распределения, такие как _alloca () и _malloca ( ) основаны на стеке ; FileMappings действительно выделяются с помощью VirtualAlloc и устанавливаются с определенными битовыми флагами, которые обозначают, что эти сопоставления относятся к типу FILE .

    В большинстве случаев вы должны распределять память таким образом, чтобы согласуется с использованием этой памяти;). новый в C ++, malloc для C, VirtualAlloc для массивных случаев или случаев IPC.

    *** Обратите внимание, большие выделения памяти, выполняемые HeapAlloc , фактически отправляются в VirtualAlloc после некоторого размера (пара сотен килобайт или 16 МБ или что-то, что я забыл, но довольно большие :)).

    *** РЕДАКТИРОВАТЬ Я кратко упомянул о IPC и VirtualAlloc , есть также кое-что очень интересное в связанном VirtualAlloc , которое никто из ответивших на этот вопрос не обсуждал.

    VirtualAlloc Пример - это то, что один процесс может использовать для выделения памяти в адресном пространстве другого процесса. Чаще всего это используется в сочетании для получения удаленного выполнения в контексте другого процесса через CreateRemoteThread (аналогично CreateThread , поток просто запускается в другой процесс).

    28
    ответ дан 24 November 2019 в 10:56
    поделиться

    VirtualAlloc => Выделяет прямо в виртуальную память, которую вы резервируете / коммитить блоками. Это отлично подходит для больших распределений, например, большие массивы.

    HeapAlloc / new => выделяет память в куче по умолчанию (или любой другой куче, которую вы можете создать). Это выделяется для каждого объекта и отлично подходит для небольших объектов. Куча по умолчанию является сериализуемой, поэтому она имеет гарантированное распределение потоков (это может вызвать некоторые проблемы в сценариях с высокой производительностью, и поэтому вы можете создавать свои собственные кучи).

    malloc => использует кучу времени выполнения C, аналогично HeapAlloc , но это обычное явление для сценариев совместимости.

    В двух словах, куча - это просто кусок виртуальной памяти, который управляется диспетчером кучи (а не необработанной виртуальной памятью)

    Последняя модель в мире памяти - это файлы с отображением памяти, этот сценарий отлично подходит для больших фрагментов данных (например, больших файлов).

    2
    ответ дан 24 November 2019 в 10:56
    поделиться

    Как сказано выше, просто поместите все данные, которые вы хотите получить обратно, в массив и закодируйте их.

    <?php
    
    echo json_encode(array(
        'html' => $html,
        'foo' => $bar,
        'bar' => $baz
    ));
    
    ?>
    

    Также, как сказано, вам не нужен json2.js. Можно выполнить синтаксический анализ данных JSON с помощью любой из ajax-функций jQuery, указав тип данных json.

    $.ajax({
        type: 'POST',
        url: 'path/to/php/script.php',
        dataType: 'json',
        data: 'foo=bar&baz=whatever',
        success: function($data) {
            var html = $data.html;
            var foo = $data.foo;
            var bar = $data.bar;
    
            // Do whatever.
        }
    });
    

    ИЗМЕНИТЬ В значительной степени то, что сказал Хория. Единственный вариант, который я мог бы увидеть, это если бы вы хотели все в том же массиве.

    Например:

    PHP:

    <?php
    
    // You have your comment array sent up as you want as $comments
    // Then just prepend the HTML string onto the beginning of your comments array.
    // So now $comments[0] is your HTML string and everything past that is your comments.
    $comments = array_unshift($comments, $your_html_string);
    
    echo json_encode($comments);
    
    ?>
    

    jQuery:

    $.ajax({
        type: 'POST',
        url: 'path/to/php/script.php',
        dataType: 'json',
        data: 'foo=bar&baz=whatever',
        success: function($comments) {
            // Here's your html string.
            var html = $comments[0];
    
            // Make sure to start at 1 or you're going to get your HTML string twice.
            // You could also skip storing it above, start at 0, and add a bit to the for loop:
            // if x == 0 then print the HTML string else print comments.
            for (var x = 1; x < $comments.length; x++) {
                // Do what you want with your comments.
                // Accessed like so:
                var name = $comments[x].name;
                var comment = $comments[x].comment;
                var datetime = $comments[x].datetime;
            }
        }
    });
    
    -121--2463759-

    Здесь можно решить несколько проблем.

    1. Браузеры вообще не разрешают перенаправление на запрос POST.

    2. redirect _ to не сохраняет формат без дополнительного ввода.

    3. Расположение хранилища не сохраняет данные формы.

    Все эти проблемы можно решить путем устранения перенаправлений.

    Вот как я передал его в прошлом:

    Вместо того, чтобы перенаправлять в required_user, рендеринг. Если фильтр перед перенаправляет или визуализирует ожидающее действие, оно отменяется. (Также нет необходимости возвращать значение false). К сожалению, этот маршрут размывает границы контроллера. Но позволяет простой HTML-откат, и предоставляет себе DRYness.

    Высокоуровневое представление нового рабочего потока будет следующим:

    1. Запрос на аннотации # vote (POST)
    2. required _ user filter fails
    3. render new session
    4. reending login information and original POST data back to annotations # vote (POST)
    5. new filter in vote захватывает информацию о сеансе и регистрируется. голосование проходит, как и ожидалось. В случае неуспешного входа вернитесь к 3.
    6. аннотации # vote redirects/renders как следует

    Начните с переработки require_user для визуализации шаблона user_sessions#new.

    def require_user
      unless current_user
        flash[:notice] = "You'll need to login or register to do that"
        @user_session ||= UserSession.new
        respond_to do |format|
          format.html {render :template => 'user_sessions/new'}
          format.js {
            render :template => 'user_sessions/new', :layout => false
          }
        end
      end
    end
    

    @ user _ session | | = UserSession.new обеспечивает возврат ошибок проверки в форму.

    Теперь мы должны увеличить ваш шаблон user_session#new, чтобы он мог запомнить действие. Кроме того, если вы планируете использовать lightboxes, это должно быть частично визуализировано соответствующими RJS или new.html.erb.

    Сначала мы создадим частичную для создания скрытых полей, сохраняющих данные POST, которые были бы потеряны при перенаправлении:

    <% if params[:controller] == "annotations" %>
      <% content_for :old_form do %>
        <%= hidden_field_tag "annotation[song_id]", params[:annotation][:song_id] %>
        <%= hidden_field_tag "annotation[vote]", params[:annotation][:vote] %>
      <% end %>
    <% end %>
    

    Затем визуализируем частичную в частичном входе, которая будет занимать ваш лайтбокс:

    <%= render :partial => vote_form_replica %>
    
    <% url = params[:controller] == "user_sessions ? user_sessions_url : {} %>
    <% form_tag @user_session, :url => url do |f| %>
      <%= yield :old_form %>
      <%= f.label :user_name %>
      <%= f.text_field :user_name %>
      <%= f.label :password %>
      <%= f.password_field :password %>
      <%= submit_tag %>
    <%end%>
    

    Пустой хэш для URL в form_tag выглядит как ошибка, но нет. Это обеспечивает разноску данных формы по URL-адресу, по которому была выполнена визуализация формы. На данном этапе должны быть аннотации/: id/vote

    Теперь для входа в систему новому фильтру. По существу, он будет делать то, что когда-либо UserExhiendureController # создает, без рендеринга/перенаправления. Следующее копируется из плагина проверки подлинности RESTful.

    def authenticate
      self.current_user = User.authenticate(params[:login], params[:password])
      if logged_in?
        if params[:remember_me] == "1"
           current_user.remember_me unless current_user.remember_token?
           cookies[:auth_token] = { :value => self.current_user.remember_token, 
             :expires => self.current_user.remember_token_expires_at }
        end
      end
    end
    

    Все, что осталось, это убедиться, что порядок фильтрации правильный.

    before_filter :authenticate, :require_user, :only => :vote
    

    Н.Б.: Вы, вероятно, не собираетесь использовать эту версию require_user без этой версии аутентификации, поэтому имеет смысл объединить их в единый фильтр.

    И все. Способ настройки обеспечивает надежный код DRY, легко используемый повторно. Размещая новые фильтры в GroupController, они доступны в любом контроллере. С этой точки зрения,Добавление этой функции к любым другим контроллерам/действиям занимает всего 3 простых шага:

    1. Создайте новую частичную часть, смоделированную после vote_form_replica частичной.
    2. Добавьте соответствующую инструкцию визуализации в новый шаблон сеанса.
    3. Примените фильтры к своим действиям.
    -121--3740488-

    Виртуальный Alloc = = > sbrk () в UNIX

    HeapAlloc = = = = > malloc () в UNIX

    4
    ответ дан 24 November 2019 в 10:56
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: