Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[107.23.85.179] |
|
Сообщ.
#1
,
|
|
|
У меня структура UDT=132байта, элементов в массиве 1,559,520. Далее не хочет работать ReDim Preserve на увеличение массива. Err.Number=9 (Subscript out of range). От чего зависит размер памяти, выделяемой под массив? Как увеличить размер массива, не меняя структуру?
Добавлено 1559520*132=205,856,640 |
Сообщ.
#2
,
|
|
|
Цитата BlackSun @ У меня структура UDT=132байта Это с учётом служебки или только размер данных? Вангую, что второе... а объём хранения на элемент байтов на 40 больше. Да и нафига такой массив? |
Сообщ.
#3
,
|
|
|
LenB=132
|
Сообщ.
#4
,
|
|
|
BlackSun
private type mytype s as string end type sub button_click() dim s as mytype s.s = "" debug.print "str len = 0, lenb=" & lenb(s) s.s = space(1024) debug.print "str len = 1024, lenb=" & lenb(s) end sub |
Сообщ.
#5
,
|
|
|
вопрос не в этом
|
Сообщ.
#6
,
|
|
|
С чего ты так думаешь? Я тебе показываю же, что рассчитанный тобой размер никак не соотносится с реально потребным под него объёмом памяти - там, где ты рассчитываешь на 200 метров, могут в реальности кушаться и все 500. А умение M$ сформулировать сообщение об ошибке, никак не соотносящееся с собственно ошибкой, известно практически каждому.
|
Сообщ.
#7
,
|
|
|
У меня нет строк в структуре. Какое ограничение памяти под массив?
Добавлено Размер служебки постоянен и равен 40б? |
Сообщ.
#8
,
|
|
|
Цитата BlackSun @ Размер служебки постоянен Нет. Цитата With user-defined types, LenB returns the in-memory size, including any padding between elements. |
Сообщ.
#9
,
|
|
|
Цитата элементов в массиве 1,559,520 Вроде не много... а в VB есть коллекции? Цитата Как увеличить размер массива, не меняя структуру? Сделать "страничное хранение". Например, есть некая коллекция из 800 000 000 элементов, но, по факту, эта коллекция не один массив, а n массивов фиксированной длинны. Организацию доступа к конкретному элементу такой коллекции придётся придумать... в vb пригодились бы property А вообще, должны быть нативные коллекции, или что то в этом роде, уверен, тот же std::vector обязанны были прикрутить каким нибудь макаром... |
Сообщ.
#10
,
|
|
|
Да ну, коллекции жутко тормозные... Мне интересно, это VB ограничивает размер массива или же нет, памяти вроде предостаточно...
|
Сообщ.
#11
,
|
|
|
Цитата VB ограничивает размер массива или же нет, памяти вроде предостаточно... Фраза "Памяти предостаточно" весьма спорная. Ты ведь не знаешь как эти элементы реально укладываются в память, и не факт что текущий уровень фрагментации памяти на это не влияет. По поводу "тормознутости" коллекций, полностью не согласен. Если правильно подбирать реализацию коллекции, разность в скорости доступа/записи к элементам массива и коллекции не будет заметна. |
Сообщ.
#12
,
|
|
|
Цитата BlackSun @ Мне интересно, это VB ограничивает размер массива или же нет, памяти вроде предостаточно... VB не должен ничего ограничивать. Если только ты сам вместо переменной Long по ошибке используешь Integer и получишь отрицательное значение UBound. А насчет памяти учти, что для Redim Preserve может понадобиться удвоенный размер памяти - под старый массив и под новый. 200+200 Мб вроде тоже не много, но тут все зависит от фрагментации адресного пространства (АП) процесса. Если ты кроме этого массива попутно сохраняешь еще какие-то объемные данные, то в итоге может оказаться, что свободное АП порублено на куски размером < 200 Мб - суммарного свободного объема "вроде предостаточно", а непрерывного куска в > 200 Мб нет |
Сообщ.
#13
,
|
|
|
Сейчас у меня массив UDT LenB=252 при 663893 элементах (итого 167млн байт данных) приводит к ошибке "Overflow". Я оказался явно зажат в какие-то тесные рамки. Может система ограничивает память процессу и можно как-то потребовать от системы выделить больше памяти?
Добавлено И как можно расчитать оптимальный размер элемента UDT, чтобы он вместе со служебными данными занимал меньше памяти? UDT внутри выравнивается по границе 4 байта вроде, а межэлементное выравнивание сколь байт будет? |
Сообщ.
#14
,
|
|
|
Цитата BlackSun @ Я оказался явно зажат в какие-то тесные рамки. Может система ограничивает память процессу и можно как-то потребовать от системы выделить больше памяти? На лицо архитектурная ошибка, а вы пытаетесь выстраивать фундамент из костылей... Для выделения доп. памяти нужно работать с x64 архитектурой программ, либо, генерить дочерние процессы, на каждый дочерний процесс вы сможете получить максимум по ~3,5ГиБ Добавлено Цитата BlackSun @ итого 167млн байт данных Как вы это узнали? Добавлено Цитата BlackSun @ UDT внутри выравнивается по границе 4 байта вроде, а межэлементное выравнивание сколь байт будет? Я не эксперт в этом, но, всё это не истинно. Есть параметры компиляции, есть оптимизация, - от всего этого один и тот же код будет генерироваться разными способами, и выравнивание будет разным. |
Сообщ.
#15
,
|
|
|
Цитата BlackSun @ Overflow Покажи структуру и как ReDim'ишь. Добавлено Цитата VisualProg @ По поводу "тормознутости" коллекций, полностью не согласен. Если правильно подбирать реализацию коллекции, разность в скорости доступа/записи к элементам массива и коллекции не будет заметна. Коллекция организует совсем другой способ хранения данных чем линейный массив. Коллекция - это красно-черное дерево - http://www.cyberforum.ru/visual-basic/thread1801288.html |
Сообщ.
#16
,
|
|
|
Цитата TheTrik @ красно-черное дерево можно графически? Public Type struFileInfo Idx As Long Info As String * 124 End Type Public aFileInfo() As struFileInfo ... ReDim Preserve aFileInfo(i) |
Сообщ.
#17
,
|
|
|
Цитата BlackSun @ можно графически? https://ru.wikipedia.org/wiki/%D0%9A%D1%80%...%B5%D0%B2%D0%BE Цитата BlackSun @ Public Type struFileInfo Idx As Long Info As String * 124 End Type Public aFileInfo() As struFileInfo ... ReDim Preserve aFileInfo(i) Здесь overflow может случится из-за переполнения переменной i. При нехватке памяти ты получишь Out of memory. |
Сообщ.
#18
,
|
|
|
Цитата TheTrik @ Коллекция организует совсем другой способ хранения данных чем линейный массив Так я ни слова не говорил ни о линейности, ни о массивах Коллекция - это всего лишь интерфейс, а реализацией уже пусть сам решает что ему надо, поведение массива, поведение связанных списков, множества, карты-словари, да что угодно. И да, хранение данных в коллекциях, как раз, реализуется таким образом, чтобы не получать такие ситуации как вышло у ТС, я же намекнул на многостраничное хранение данных и множества более мелких массивов) Автор же настаивает на массиве-монстре, всё в одном, да ещё и в линейном виде... |
Сообщ.
#19
,
|
|
|
Цитата VisualProg @ Так я ни слова не говорил ни о линейности, ни о массивах Имелась в виду встроенная в VB6 реализация коллекции которую я привел по ссылке - Collection. Цитата VisualProg @ И да, хранение данных в коллекциях, как раз, реализуется таким образом, чтобы не получать такие ситуации как вышло у ТС Мы еще не выяснили что там произошло у ТС, поскольку его ошибка вызвана не нехваткой памяти. За нелинейность придется также заплатить фрагментацией, скоростью и дополнительной памятью. Большой линейный массив данных нужно организовывать через файл-маппинг. |
Сообщ.
#20
,
|
|
|
Цитата TheTrik @ Здесь overflow может случится из-за переполнения переменной i i As Long Ошибка при i=663893. err.Description="Out of memory" Цитата VisualProg @ что имеется ввиду? многостраничное хранение данных |
Сообщ.
#21
,
|
|
|
Цитата BlackSun @ i As Long Redim не генерирует Overflow исключение. |
Сообщ.
#22
,
|
|
|
Сейчас выдало Out of memory, но ранее было Overflow, удивительно... Хотя, может я что-то напутал.
|
Сообщ.
#23
,
|
|
|
Цитата BlackSun @ Сейчас выдало Out of memory, но ранее было Overflow, удивительно... Хотя, может я что-то напутал. Значит не хватает нужного куска памяти. Меняй организацию данных. Во-первых, все ли 124 символа всегда используются? МБ сделать ее динамической? Во-вторых, String - UNICODE строка, нужен ли юникод? МБ обойтись многобайтовой реализацией? В-третьих, если доступ к данным в основном последовательный (не рандомный), то сделай фиксированный буфер и перехватывай ошибку обращения вне диапазона - подгружай нужную часть и корректируй индекс - идеально через файл-маппинг, система сама будет обновлять данные. |
Сообщ.
#24
,
|
|
|
Строка используется полностью, но что-то ужимать (пусть и в 2 раза за счёт байтового массива) - для меня не выход. Можно одновременно держать в памяти часть массива, это куча доп. кода для каждой простой операции, как, например, поиск в массиве. Если бы VB позволял создавать "постраничные" массивы, где первый индекс массива указывает на страницу(массив-страницу в памяти), то лучше бы я переписал код для работы с таким массивом.
|
Сообщ.
#25
,
|
|
|
Цитата BlackSun @ Можно одновременно держать в памяти часть массива, это куча доп. кода для каждой простой операции, как, например, поиск в массиве. Нет. На доступе это никак не скажется, разница только при подгрузке которая ловится перехватом исключения. Цитата BlackSun @ Если бы VB позволял создавать "постраничные" массивы, где первый индекс массива указывает на страницу(массив-страницу в памяти), то лучше бы я переписал код для работы с таким массивом. Ничто не мешает создать такой. |
Сообщ.
#26
,
|
|
|
Цитата TheTrik @ Как? Ничто не мешает создать такой. |
Сообщ.
#27
,
|
|
|
Цитата BlackSun @ Как? Public Type struFileInfo Idx As Long Info As String * 124 End Type Private Type tPage tData() As struFileInfo End Type Public aFileInfo() As tPage |
Сообщ.
#28
,
|
|
|
Цитата BlackSun @ что имеется ввиду? Цитата VisualProg @ Сделать "страничное хранение". Например, есть некая коллекция из 800 000 000 элементов, но, по факту, эта коллекция не один массив, а n массивов фиксированной длинны. Организацию доступа к конкретному элементу такой коллекции придётся придумать... За длину такого фиксированного массива можно брать, например 100 элементов. Далее, для того чтобы записать 400 000 000 элементов, тебе необходимо сгенерировать 4 000 000 массивов по 100 элементов, всё просто. Непрерывное свободное место объёмом в 100 элементов с куда бОльшей долей вероятности встретиться в ОЗУ, и, естественно, такие массивы уложить в памяти проще. Это я тебе пример привёл для поведения как у массива. Если же ты будешь использовать связный список - то там вообще не надо заморачиваться, он хранится по 1 элементу в памяти. Единственный минус связных списков - невозможно получить доступ к конкретному элементу сразу, для этого надо пройтись от начала или от конца списка по всей цепочки, и найти нужный элемент. Зато, добавление новых элементов, и удаление старых - моментальное. Короче, всё это - основы, я тебе уже книжки пересказываю, мог бы и сам почитать... |
Сообщ.
#29
,
|
|
|
TheTrik мне нужно постраничное хранение в памяти, а не постраничное чтение из файла, хотя, экономия памяти - тоже выгода. VisualProg, да про списки-то я знаю, а вот уверены, что коллекция лежит в памяти кусками? Сейчас потестим.
|
Сообщ.
#30
,
|
|
|
Цитата BlackSun @ TheTrik мне нужно постраничное хранение в памяти, а не постраничное чтение из файла, хотя, экономия памяти - тоже выгода. Файл маппинг - для больших линейных массивов данных. Если у тебя не очень большой массив, то можешь делать как тут Максимальный размер массива UDT. |
Сообщ.
#31
,
|
|
|
Цитата BlackSun @ а вот уверены, что коллекция лежит в памяти кусками? В реализациях коллекций на java, c#, c++ у меня нет сомнений. Там всё сделано грамотно, не думаю что VB в этом отличается. В нём так же, должно быть всё это учтено. Тем более, если TheTrik утверждает что там дерево, так это же вообще, по сути, связный список, но, не в линейной форме, а в виде дерева. |