Почему я должен получить ошибку памяти с помощью pandas? [Дубликат]

[Д2] 1. ОПРЕДЕЛЕНИЕ ПРОБЛЕМЫ РАСПРЕДЕЛЕНИЯ

Если D - производный класс базового класса B, то вы можете назначить объект типа Derived переменной (или параметру) типа Base.

ПРИМЕР

class Pet
{
 public:
    string name;
};
class Dog : public Pet
{
public:
    string breed;
};

int main()
{   
    Dog dog;
    Pet pet;

    dog.name = "Tommy";
    dog.breed = "Kangal Dog";
    pet = dog;
    cout << pet.breed; //ERROR

Хотя указанное назначение разрешено, значение, присвоенное переменной pet, теряет поле породы. Это называется проблемой нарезки.

2. КАК ИЗМЕНИТЬ ПРОБЛЕМУ СЦЕПЛЕНИЯ

Чтобы устранить проблему, мы используем указатели на динамические переменные.

ПРИМЕР

Pet *ptrP;
Dog *ptrD;
ptrD = new Dog;         
ptrD->name = "Tommy";
ptrD->breed = "Kangal Dog";
ptrP = ptrD;
cout << ((Dog *)ptrP)->breed; 

В этом случае ни один из элементов данных или функций-членов динамической переменной, на которые указывает ptrD (объект класса потомка), будет потерян. Кроме того, если вам нужно использовать функции, функция должна быть виртуальной.

17
задан Saullo G. P. Castro 16 August 2013 в 23:18
поделиться

1 ответ

Я не знаю, почему вы думаете, что ваш процесс должен иметь доступ к 4 ГБ. Согласно Ограничениям памяти для выпуска Windows в MSDN, в 64-разрядной Windows 7, 32-разрядный процесс по умолчанию получает 2 ГБ. * Именно это и заканчивается.

So , есть ли способ обойти это?

Ну, вы можете создать пользовательскую сборку из 32-разрядного Python, которая использует флаг IMAGE_FILE_LARGE_ADDRESS_AWARE, и перестроить numpy и все ваши другие модули расширения. Я не могу обещать, что весь соответствующий код действительно безопасен для работы с флагом с большим адресом; есть хороший шанс, но если кто-то уже это сделал и не протестировал, «хороший шанс» - это лучший, кого, вероятно, узнают.

Или, что более очевидно, просто используйте 64-битный Python вместо этого .


Объем физической ОЗУ полностью не имеет значения. Кажется, вы думаете, что у вас есть «ограничение 8 ГБ» с 8 ГБ ОЗУ, но это не так, как это работает. Ваша система занимает всю вашу RAM плюс любое место подкачки, в котором она нуждается , и делит ее между приложениями; приложение может получить 20 ГБ виртуальной памяти, не получая ошибку памяти даже на машине 8 ГБ. Между тем, 32-разрядное приложение не имеет доступа к более чем 4 ГБ, и ОС будет использовать некоторые из этих адресных пространств (половина из них по умолчанию в Windows), поэтому вы можете получить только 2 ГБ даже на машине с 8 ГБ это ничего не работает. (Нельзя сказать, что когда-либо можно «ничего не запускать» на современной ОС, но вы знаете, что я имею в виду.)


Итак, почему это работает на вашем Linux-поле?

Поскольку ваш Linux-модуль настроен на предоставление 32-битных процессов 3,5 ГБ виртуального адресного пространства, или 3,99 ГБ, или ... Ну, я не могу сказать вам точный номер, но каждый дистрибутив, который я видел для много лет был настроен как минимум на 3,25 ГБ.


* Также обратите внимание, что вы даже не получаете полные 2 ГБ для своих данных; вашей программы. Большая часть того, что ОС и его драйверы делают доступными для вашего кода, находится в другой половине, но некоторые биты сидят в вашей половине, вместе с каждой загружаемой DLL и любым необходимым пространством и другими вещами. Это не слишком много, но это не ноль.

34
ответ дан abarnert 21 August 2018 в 09:46
поделиться
  • 1
    На самом деле вам не нужно компилировать exe на windows, IMAGE_FILE_LARGE_ADDRESS_AWARE - это всего лишь флаг в заголовке изображения (не то, что это когда-либо официально поддерживалось, но мы не судим;)). Кроме того, dlls не имеют права говорить в этом вопросе, чтобы начать, так что их не нужно менять в любом случае. – Voo 16 August 2013 в 23:54
  • 2
    @Voo: но весь ваш код, включая ваши DLL, должен быть безопасным для использования с включенным флагом. Если, скажем, Python и его стандартные модули расширения проверяют во время сборки, хотите ли вы поддерживать поддержку большого адреса и генерировать другой код в разных случаях, вам нужно будет перестроить все, а не только exe. Если они всегда с большим адресом, вам не нужно ничего делать. И если они никогда защищены большими адресами, то перестройка не поможет. Я не знаю никакой документации, которая говорит вам, какая из трех она ... – abarnert 17 August 2013 в 01:59
  • 3
    Правда, хотя единственная причина, по которой код не сработает с IMAGE_FILE_LARGE_ADDRESS_AWARE, заключается в том, что он сломан для начала (подписанная математика указателя) или делает глупые трюки с битом верхнего порядка указателей. Я очень удивлен, что python делает это - где именно в коде? (GC Я предполагаю, что это почти единственная причина, по которой это может быть полезно). Хотелось бы посмотреть на это. – Voo 17 August 2013 в 15:28
  • 4
    @Voo: У меня нет абсолютно никакой идеи, если Python или любые модули Python, от которых зависит OP, делают такую ​​вещь. Я не думаю, что это возможно, но я не могу этого гарантировать. Очевидно, что по какой-то причине он не построен с IMAGE_FILE_LARGE_ADDRESS_AWARE из коробки; я предполагаю, что причина в том, что до сих пор ни один из разработчиков никогда не обнаружил, что стоит тестировать и / или очищать исходный код, потому что, если им действительно нужно больше 2 ГБ, они просто используют 64-битную сборку. Но это всего лишь предположение, поэтому мой ответ сказал, что есть хорошие шансы, что это сработает, но я не могу обещать. – abarnert 19 August 2013 в 20:22
  • 5
    Да, но если нет компилятора для этого, что python зависит от того, что тогда все работы по перестройке python будут делать ровно ничто по сравнению с просто изменением одного бита в заголовке, который был моей точкой. И я действительно не вижу, как python может использовать все, что полагается на бит высокого порядка, неиспользуемый - ведь * nix обычно не дает таких гарантий, и там работает python. – Voo 19 August 2013 в 20:33
Другие вопросы по тегам:

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