Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Массив строк и память, как подружить 
:(
    Опции темы
serghd
Дата 28.1.2010, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Смысл в том, чтобы забить list 75к массивами.
Делал цикл на 75000 итераций:
Код

   ArrayList list = new ArrayList();
   for (int i = 0; i < 75000; i ++)
   {
    String[] mas = {"text" + i, "text2" + i};
    list.add(mas);    
   }

JVM вылетает, как я понимаю из-за нехватки памяти. Пробовал также создать массив вне цикла:
Код

   ArrayList list = new ArrayList();
   String[] mas = new String[2];
   for (int i = 0; i < 75000; i ++)
   {
    mas[0] = "text" + i;
    mas[1] = "text2" + i;
    list.add(mas);    
   }

Но в этом случае, поскольку массив содержит только ссылки на объекты, в list сохранится 75к массивов только со значениями последней итерации (изменение элементов массива отразится также на всех массивах list'a).
Код максимально упростил, чтобы оставить только суть, на самом деле парсится xml. Спасибо.

Это сообщение отредактировал(а) serghd - 28.1.2010, 16:45
PM MAIL   Вверх
LSD
Дата 28.1.2010, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



И в чем вопрос-то? Увеличь память, или перейди на два листа.

Добавлено через 1 минуту и 4 секунды
Или даже 2 массива.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 28.1.2010, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



так увеличивал, такая же проблема как в последнем посте тут. Не помогает это

Это сообщение отредактировал(а) serghd - 28.1.2010, 17:28
PM MAIL   Вверх
LSD
Дата 28.1.2010, 17:31 (ссылка) |  (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Или переходи на 64 битную JVM или на два листа.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 28.1.2010, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(LSD @ 28.1.2010,  17:31)
Или переходи на 64 битную JVM или на два листа.

>>Или переходи на 64 битную JVM
как, можно по-подробнее?
>>или на два листа
а что, два ArrayList'a занимают меньше чем один большой?
PM MAIL   Вверх
LSD
Дата 28.1.2010, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(serghd @  28.1.2010,  17:36 Найти цитируемый пост)
как, можно по-подробнее?

Ставишь 64-х битную ОС, а на нее 64-х битную JVM smile



Цитата(serghd @  28.1.2010,  17:36 Найти цитируемый пост)
а что, два ArrayList'a занимают меньше чем один большой? 

Два ArrayList-а занимают места меньше чем один ArrayList и 75000 массивов String[].


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
andrew_121
Дата 28.1.2010, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: нет
Всего: 33



LSD, простите что я в чужую тему вклиниваюсь, просто любопытно стало.
несколько вопросов.
для начала код:
Код


package javaapplication1;
import java.util.ArrayList;
import java.util.Random;
import org.omg.CORBA.SystemException;

class Item {
    String f1;
    String f2;
    String f3;
    String f4;
    String f5;
    String f6;
    String f7;
    String f8;
}

public class Main {
    public static Item get_item() {
        Item item = new Item();
        item.f1 = new Random().toString();
        item.f2 = new Random().toString();
        item.f3 = new Random().toString();
        item.f4 = new Random().toString();
        item.f5 = new Random().toString();
        item.f6 = new Random().toString();
        item.f7 = new Random().toString();
        item.f8 = new Random().toString();
        return item;
    }

    public static void main(String[] args) {
        ArrayList<Item> item_list = new ArrayList<Item>();
        try {
            for ( int i = 0; i < 100000; ++i ) {
                item_list.add(get_item());
            }
        } catch(java.lang.OutOfMemoryError e) {
            System.out.println(item_list.size());
        }
    }
}

вылетает на 88256 элементов.

1. если по умолчанию ВМ выделяет 64мб памяти, и этой памяти не хватает для 100к элементов, а только для 88256, полагаю, что в обработчике исключения нужно выделить еще памяти.
2. как в коде(не с помощью ключей) ее выделить?
3. как можно узнать объем объекта(не выделенной памяти)? в с++ есть оператор sizeof().
4. равноправно ли правило, что строка состоящая из 10-ти символов занимает 10 байт памяти ВМ?

спасибо.

Добавлено через 42 секунды
Цитата(LSD @  28.1.2010,  17:45 Найти цитируемый пост)
Два ArrayList-а занимают места меньше чем один ArrayList и 75000 массивов String[]. 

поясните пожалуйста. почему так?


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
serghd
Дата 28.1.2010, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(LSD @ 28.1.2010,  17:45)
Цитата(serghd @  28.1.2010,  17:36 Найти цитируемый пост)
как, можно по-подробнее?

Ставишь 64-х битную ОС, а на нее 64-х битную JVM smile

И мне это рекомендовать всем, у кого будет программа?

Это сообщение отредактировал(а) serghd - 28.1.2010, 18:26
PM MAIL   Вверх
LSD
Дата 28.1.2010, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
1. если по умолчанию ВМ выделяет 64мб памяти, и этой памяти не хватает для 100к элементов, а только для 88256, полагаю, что в обработчике исключения нужно выделить еще памяти.

Тут все не так просто smile Во первых - 64 Мб памяти это на всех, включая служебные данные самой JVM (поток сборки мусора, загруженные классы и т.п.). Во вторых ArrayList когда у него заканчивается место в массиве (который используется для хранения) создает новый больше предыдущего в 1.5 раза, а потом копирует туда данные из старого. И значит в какой-то момент времени памяти должно быть достаточно на 2 достаточно больших массива. В третьих если уж вылетел OutOfMemoryError, то ArrayList находится непонятно в каком состоянии (вернее он точно находится в неконсистентном состоянии).


Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
2. как в коде(не с помощью ключей) ее выделить?

Никак.



Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
3. как можно узнать объем объекта(не выделенной памяти)? в с++ есть оператор sizeof().

Честно - нет. А так создают много одинаковых объектов и смотрят, сколько они занимают места. Еще есть извраты через unsafe, рефлексию и т.д.



Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
4. равноправно ли правило, что строка состоящая из 10-ти символов занимает 10 байт памяти ВМ?

1. Один символ занимает 2 байта (это же Unicode).
2. Строка это объект и у нее есть еще данные кроме самих символов. Да и массив символов тоже потребляет место.
3. Строки могут совместно использовать массивы символов.
4. Некоторые ссылки на строку, могут быть ссылкой на одну и ту же строку.




Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
поясните пожалуйста. почему так?

Массив это объект. Как и любой объект у него есть накладные расходы: 8 байт на заголовок, 4 байта на длинну, и на данные. В случае с массивом объектов длинны 2 это будет 4*2 байта. Вот и считай, что лучше 2 * (8 + 4 + 75000 * 4) или (8 + 4 + 75000 * 4) + 75000 * (8 + 4 + 2* 4).


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
andrew_121
Дата 28.1.2010, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: нет
Всего: 33



Цитата(serghd @  28.1.2010,  18:24 Найти цитируемый пост)
И мне это рекомендовать всем, у кого будет программа?

я думаю должна быть возможность "попросить" у ВМ, больше памяти, программно.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
LSD
Дата 28.1.2010, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(serghd @  28.1.2010,  18:24 Найти цитируемый пост)
И мне это рекомендовать всем, у кого будет программа?

Твоя программа жрет слишком много памяти, это все что можно сказать из твоего кода и объяснения. И ты хочешь чтобы тебе подсказали как уменьшить потребление памяти, при этом вообще ничего не рассказывая ни про алгоритм работы, не показывая кода, вообще ничего кроме маленького примера, который вообще неизвестно насколько близок к реальной проблеме. И ты считаешь что это реально?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
andrew_121
Дата 28.1.2010, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: нет
Всего: 33



LSD, спасибо за разъяснение. многое прояснилось.
а по поводу программного перевыделения памяти - жаль конечно smile 

я уже подумал что можно "по человечески" разрулить ситуацию. типа этого:
Код


package javaapplication1;
import java.util.ArrayList;
import java.util.Random;
import org.omg.CORBA.SystemException;

/**
 *
 * @author nixman
 */
class Item {
    String f1;
    String f2;
    String f3;
    String f4;
    String f5;
    String f6;
    String f7;
    String f8;
}

public class Main {
    public static Item get_item() {
        Item item = new Item();
        item.f1 = new Random().toString();
        item.f2 = new Random().toString();
        item.f3 = new Random().toString();
        item.f4 = new Random().toString();
        item.f5 = new Random().toString();
        item.f6 = new Random().toString();
        item.f7 = new Random().toString();
        item.f8 = new Random().toString();
        return item;
    }
    
    static int stepsize = 32*1024*1024;/* мегабайт */
    static int limit = 1024*1024*1024;/* гигабайт */
    static int allocated = stepsize; /* инициализируем размером шага */

    public static void main(String[] args) {
        ArrayList<Item> item_list = new ArrayList<Item>();
        try {
            for ( int i = 0; i < 100000; ++i ) {
                item_list.add(get_item());
            }
        } catch(java.lang.OutOfMemoryError e) {
            System.out.println(item_list.size());
            /* проверяем на разумный предел */
            if ( allocated+stepsize < limit ) {
                /* тут выделяем память */
               main(args); /* перезапускаем */
            }
        }
    }
}


тем не менее, всем спасибо.

UP

Это сообщение отредактировал(а) andrew_121 - 28.1.2010, 18:44


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
LSD
Дата 28.1.2010, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(andrew_121 @  28.1.2010,  18:40 Найти цитируемый пост)
я уже подумал что можно "по человечески" разрулить ситуацию. типа этого

Ну можно попробовать пересоздать ArrayList и вызвать у него ensureCapacity() увеличив его немного по сравнению с предыдущим результатом.

Просто в реальных приложениях такая работа на грани означает, что надо что-то радикально менять в алгоритме и/или железе (перейти на 64 бита или нарастить память).


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
ernando
Дата 28.1.2010, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 3.1.2007

Репутация: нет
Всего: нет



serghd, а можешь описать входные условия, ради чего тебе в памяти нужно дербанить 75к объектов, тем более массивов? Просто за все вермя работы в IT не приходилось гонять такие объемы, если это не было узкоспециализированной задачей, но там уже действительно выбирается другое железо и тюнится сама JVM.
PM   Вверх
LSD
Дата 28.1.2010, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Кстати в данном случае, можно в класс Item добавить ссылку на следующий элемент и таким образом организовать связный список. Если нужна только однонаправленная итерация по списку, то это будет самый экономный способ динамического выделения памяти smile


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 28.1.2010, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(ernando @ 28.1.2010,  18:47)
serghd, а можешь описать входные условия, ради чего тебе в памяти нужно дербанить 75к объектов, тем более массивов? Просто за все вермя работы в IT не приходилось гонять такие объемы, если это не было узкоспециализированной задачей, но там уже действительно выбирается другое железо и тюнится сама JVM.

диапазоны IP адресов стран, нужно их перебирать для выяснения к какой стране относится ip. Для перебора - пропарсить xml с ними (каждый item будет иметь 6 типов данных - страна, ip_start, ip_end и др., поэтому и массив) и поместить в ArrayList, с которым потом и сравнивать. 
Почему установка VM Options -Xmx1600M не помогает, ей что, для такого массива надо больше 1600 мегабайт??

Это сообщение отредактировал(а) serghd - 28.1.2010, 19:01
PM MAIL   Вверх
andrew_121
Дата 28.1.2010, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: нет
Всего: 33



Цитата(LSD @  28.1.2010,  18:45 Найти цитируемый пост)
Ну можно попробовать пересоздать ArrayList и вызвать у него ensureCapacity() увеличив его немного по сравнению с предыдущим результатом.

да, один из вариантов.


Цитата(LSD @  28.1.2010,  18:45 Найти цитируемый пост)
Просто в реальных приложениях такая работа на грани означает, что надо что-то радикально менять в алгоритме и/или железе (перейти на 64 бита или нарастить память). 

понимаю.


Цитата(ernando @  28.1.2010,  18:47 Найти цитируемый пост)
ради чего тебе в памяти нужно дербанить 75к объектов, тем более массивов?

мне тоже интересно smile
75к объектов, это нормально.


Цитата(LSD @  28.1.2010,  18:48 Найти цитируемый пост)
Кстати в данном случае, можно в класс Item добавить ссылку на следующий элемент и таким образом организовать связный список. Если нужна только однонаправленная итерация по списку, то это будет самый экономный способ динамического выделения памяти

велосипед?

кстати в моем варианте кода, получилось создать 100к объектов. просто добавил опцию для ВМ -Xmx128M.
того, в сумме создано 800 000 строк. замечу не мало smile 


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
LSD
Дата 28.1.2010, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(serghd @  28.1.2010,  18:58 Найти цитируемый пост)
ей что, для такого массива надо больше 1600 мегабайт??

Сам ArrayList будет занимать около 75 килобайт, остальное твои объекты.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
jk1
Дата 28.1.2010, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



serghd, почему вы так уверены что дело именно в массиве? Вы профайлер запускали, смотрели, кто именно жрет память?


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
serghd
Дата 28.1.2010, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(LSD @ 28.1.2010,  19:12)
Цитата(serghd @  28.1.2010,  18:58 Найти цитируемый пост)
ей что, для такого массива надо больше 1600 мегабайт??

Сам ArrayList будет занимать около 75 килобайт, остальное твои объекты.

Какие мои, кроме 75к String[] и одного ArrayList практически ничего нет в программе!
PM MAIL   Вверх
LSD
Дата 28.1.2010, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(serghd @  28.1.2010,  19:15 Найти цитируемый пост)
Какие мои, кроме 75к String[] и одного ArrayList практически ничего нет в программе! 

1. Я говорил про ArrayList, но не про 75к String[].
2. 
Код

  public static void main(String[] args)
  {
    ArrayList<String[]> list = new ArrayList<String[]>();
    for (int i = 0; i < 75000; i ++)
    {
     String[] mas = {"text" + i, "text2" + i};
     list.add(mas);
    }
    logger.info("list.si = " + list.size());
  }

спокойно отрабатывает и на 64 Мб.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 28.1.2010, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(LSD @ 28.1.2010,  19:20)
Цитата(serghd @  28.1.2010,  19:15 Найти цитируемый пост)
Какие мои, кроме 75к String[] и одного ArrayList практически ничего нет в программе! 

1. Я говорил про ArrayList, но не про 75к String[].
2. 
Код

  public static void main(String[] args)
  {
    ArrayList<String[]> list = new ArrayList<String[]>();
    for (int i = 0; i < 75000; i ++)
    {
     String[] mas = {"text" + i, "text2" + i};
     list.add(mas);
    }
    logger.info("list.si = " + list.size());
  }

спокойно отрабатывает и на 64 Мб.

Этот срабатывает и у меня.
Но реальная задача:
VM Options: -Xmx512m (запуск нормальный, т.е. было выделено)
Код всей программы (для разбора xml используется qt jambi):
Код

 public static void main(String[] args)
 {
  ArrayList<String[]> geoIp = new ArrayList<String[]>();

  QFile xmlFile = new QFile("geoip.xml");
  if (!xmlFile.exists()) System.out.println("file not exists");
  else
  {
   QDomDocument doc = new QDomDocument();
   doc.setContent(xmlFile);
   QDomElement docElement = doc.documentElement();
   QDomElement node = docElement.firstChildElement();

   while(!node.isNull())
   {
    String[] mas = new String[6];
    mas[0] = node.attribute("ip_start");
    mas[1] = node.attribute("ip_end");
    mas[2] = node.attribute("num_ip_start");
    mas[3] = node.attribute("num_ip_end");
    mas[4] = node.attribute("flag");
    mas[5] = node.text();
    geoIp.add(mas);

    node = node.nextSiblingElement();
   }
  }
 }

Всего 70040 строк. Без "geoIp.add(mas);" 1 секунда работы без ошибок. С ним вылетает.



Это сообщение отредактировал(а) serghd - 28.1.2010, 20:07
PM MAIL   Вверх
andrew_121
Дата 28.1.2010, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: нет
Всего: 33



смотрю на код, и не въезжаю...какой же тайный смысл кроется в -
Цитата(serghd @  28.1.2010,  19:45 Найти цитируемый пост)
ArrayList<String[]> geoIp = new ArrayList<String[]>();

почему бы не воспользоваться классом состоящим их шести полей типа строки?
в таком случае, ситуация немного измениться по двум причинам:
1. класс с шестью строками != массив строк. возможно и памяти для него требуется меньше.
2. свойства класса можно назвать внятными именами, соответственно, работать с ним проще.
3. это:
Цитата(serghd @  28.1.2010,  19:45 Найти цитируемый пост)
    String[] mas = new String[6];
    mas[0] = node.attribute("ip_start");
    mas[1] = node.attribute("ip_end");
    mas[2] = node.attribute("num_ip_start");
    mas[3] = node.attribute("num_ip_end");
    mas[4] = node.attribute("flag");
    mas[5] = node.text();

выглядит как-то нелепо, батарею напоминает smile

в общем, простите новичка, если глупость сказал smile 

Это сообщение отредактировал(а) andrew_121 - 28.1.2010, 21:09


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
serghd
Дата 28.1.2010, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(andrew_121 @ 28.1.2010,  21:08)
смотрю на код, и не въезжаю...какой же тайный смысл кроется в -
Цитата(serghd @  28.1.2010,  19:45 Найти цитируемый пост)
ArrayList<String[]> geoIp = new ArrayList<String[]>();

почему бы не воспользоваться классом состоящим их шести полей типа строки?

потому что результат тот же. На всякий случай:
Код

  public static void main(String[] args)
 {
  QFile xmlFile = new QFile("geoip.xml");
  if (!xmlFile.exists()) System.out.println("file not exists");
  else
  {
   QDomDocument doc = new QDomDocument();
   doc.setContent(xmlFile);
   QDomElement docElement = doc.documentElement();
   QDomElement node = docElement.firstChildElement();

   ArrayList<GeoIPNode> geoIp = new ArrayList<GeoIPNode>();

   while(!node.isNull())
   {
    GeoIPNode geoNode = new GeoIPNode();
    geoNode._ip_start = node.attribute("ip_start");
    geoNode._ip_end = node.attribute("num_ip_end");
    geoNode._num_ip_start = node.attribute("num_ip_start");
    geoNode._num_ip_end = node.attribute("num_ip_end");
    geoNode._flag = node.attribute("flag");
    geoNode._country_name = node.text();
                                      
    geoIp.add(geoNode);
    node = node.nextSiblingElement();
   }
  }
 }


public class GeoIPNode
{
 String _ip_start, _ip_end, _num_ip_start, _num_ip_end, _flag, _country_name;
}





Цитата(andrew_121 @ 28.1.2010,  21:08)

String[] mas = new String[6];
    mas[0] = node.attribute("ip_start");
    mas[1] = node.attribute("ip_end");
    mas[2] = node.attribute("num_ip_start");
    mas[3] = node.attribute("num_ip_end");
    mas[4] = node.attribute("flag");
    mas[5] = node.text();

берутся аттрибуты item'a, батарея будет в любом случае, это не "Random()". У меня такой массив без вылета работает максимум на 25 000 итераций, если без установок. С -Xmx512m вобщем-то тоже самое.
Пробовал также делить 75к на 7 частей и пихать их в отдельные Vector'ы, потом группировать в один, то же самое.

Это сообщение отредактировал(а) serghd - 28.1.2010, 21:42
PM MAIL   Вверх
serghd
Дата 28.1.2010, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



дело было именно в xml, либо реализации механизма работы с ним со стороны jambi. Забивает память, что больше 20к строк лучше не запоминать. Попробовал считывать данные из csv-формата (построчно как обычный текстовый файл) и заносить их в ArrayList - всё норм.
PM MAIL   Вверх
LSD
Дата 29.1.2010, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(serghd @  28.1.2010,  19:45 Найти цитируемый пост)
для разбора xml используется qt jambi

Ну вот нафига? Есть же SAX/StAX, которые в данной ситуации намного лучше подходят.

Да и хранить IP в строке, тоже как минимум "странно".


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 29.1.2010, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(LSD @ 29.1.2010,  10:51)
Цитата(serghd @  28.1.2010,  19:45 Найти цитируемый пост)
для разбора xml используется qt jambi

Ну вот нафига? Есть же SAX/StAX, которые в данной ситуации намного лучше подходят.

Да и хранить IP в строке, тоже как минимум "странно".


>>Есть же SAX/StAX
Я использую DOM, а не SAX и jambi(при том, что весь проект на ней основан) для этого является очень удобным инструментом. Откуда мне было знать, что цикл с ним с более 20к итераций вызовет memory overflow.

>>Да и хранить IP в строке, тоже как минимум "странно".
А где же их ещё хранить? Там не только один ip. В БД типа mysql?)
Парсится всё равно только 1 раз во время загрузки программы.
Пример одного нода:
<country ip_start="2.6.190.56" ip_end="2.6.190.63" num_ip_start="33996344" num_ip_end="33996351" flag="GB" >United Kingdom</country>

Это сообщение отредактировал(а) serghd - 29.1.2010, 14:08
PM MAIL   Вверх
LSD
Дата 29.1.2010, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(serghd @  29.1.2010,  14:04 Найти цитируемый пост)
А где же их ещё хранить?

С точки зрения экономии памяти - int для IPv4, или long, тогда будет проще сравнивать.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 29.1.2010, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



да, но в любом случае мне придётся конвертировать. Аттрибуты num_ip_start="33996344"  и num_ip_end="33996351" содержат числовое представление ip, которое и буду переводить в int для сравнения. А что, можно разве как-то реализовать без конвертирования?
PM MAIL   Вверх
LSD
Дата 29.1.2010, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Я не совсем понял, что такое num_ip_start, что это за число?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 29.1.2010, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Диапазон от num_ip_start до num_ip_end равноценен диапазону ip-адресов ip_start до ip_end. Путём простого преобразования их можно переводить один в другой. Сделано специально для удобства определения входит Ip в диапазон или нет.
PM MAIL   Вверх
LSD
Дата 29.1.2010, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Я не понял, как это число связано с IP адресом? Это просто IP представленный как int, так?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 29.1.2010, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(LSD @ 29.1.2010,  14:58)
Я не понял, как это число связано с IP адресом? Это просто IP представленный как int, так?

да

Добавлено @ 15:14
простой код 
Код

   DOMParser parser = new DOMParser();
   try {
    parser.parse("geoip.xml");
   } catch (SAXException ex) {
    Logger.getLogger(Ui_Form.class.getName()).log(Level.SEVERE, null, ex);
   } catch (IOException ex) {
    Logger.getLogger(Ui_Form.class.getName()).log(Level.SEVERE, null, ex);
   }
   Document doc = parser.getDocument();

   NodeList nodes = doc.getElementsByTagName("country");
   System.out.println("There are " + nodes.getLength() +
      "  elements.");

с использованием xerces тоже выдал ошибку о переполнении. Блин, придётся наверно отказаться от xml, и парсить обычный текстовый файл.
Хотя установка -Xmx256m на этот раз помогла.

Это сообщение отредактировал(а) serghd - 29.1.2010, 15:18
PM MAIL   Вверх
LSD
Дата 29.1.2010, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Используй StAX. (если выложишь пример XML, могу попробовать наваять примерчик)


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 29.1.2010, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE geoIp>
<countries>
 <country ip_start="2.6.190.56" ip_end="2.6.190.63" num_ip_start="33996344" num_ip_end="33996351" flag="GB" >United Kingdom</country>
 <country ip_start="3.0.0.0" ip_end="4.17.135.31" num_ip_start="50331648" num_ip_end="68257567" flag="US" >United States</country>
 <country ip_start="4.17.135.32" ip_end="4.17.135.63" num_ip_start="68257568" num_ip_end="68257599" flag="CA" >Canada</country>
 <country ip_start="4.17.135.64" ip_end="4.17.142.255" num_ip_start="68257600" num_ip_end="68259583" flag="US" >United States</country>
 <country ip_start="4.17.143.0" ip_end="4.17.143.15" num_ip_start="68259584" num_ip_end="68259599" flag="CA" >Canada</country>
</countries>
Спасиб.
PM MAIL   Вверх
Amp
Дата 29.1.2010, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 886
Регистрация: 17.2.2009

Репутация: 3
Всего: 17



Если уж хочется завязки на QtJambi, то в модуле QtXml есть необходимые средства - глава про "The Qt SAX2 Classes".
PM MAIL   Вверх
serghd
Дата 29.1.2010, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(Amp @ 29.1.2010,  15:36)
Если уж хочется завязки на QtJambi, то в модуле QtXml есть необходимые средства - глава про "The Qt SAX2 Classes".

Так я и так использовал jambi, но DOM. А что, в моём случае (~75000 нодов) SAX наверняка поможет?
PM MAIL   Вверх
Amp
Дата 29.1.2010, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 886
Регистрация: 17.2.2009

Репутация: 3
Всего: 17



Цитата(serghd @  29.1.2010,  15:38 Найти цитируемый пост)
Так я и так использовал jambi, но DOM. А что, в моём случае (~75000 нодов) SAX наверняка поможет? 

Потребление памяти самим SAX-парсером практически не зависит от размеров исходного xml-документа и достаточно мало. В отличии от DOM-парсеров, где надо в памяти хранить дерево со считанными элементами/нодами. Почитайте как это работает - все станет ясно.

Это сообщение отредактировал(а) Amp - 29.1.2010, 19:03
PM MAIL   Вверх
serghd
Дата 29.1.2010, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



Цитата(Amp @ 29.1.2010,  19:03)
Цитата(serghd @  29.1.2010,  15:38 Найти цитируемый пост)
Так я и так использовал jambi, но DOM. А что, в моём случае (~75000 нодов) SAX наверняка поможет? 

Потребление памяти самим SAX-парсером практически не зависит от размеров исходного xml-документа и достаточно мало. В отличии от DOM-парсеров, где надо в памяти хранить дерево со считанными элементами/нодами. Почитайте как это работает - все станет ясно.

спасибо, а у вас случайно нету практического примера на jambi хоть какого-нибудь? А то в инете весьма трудно найти, максимум на с++. Тролли и так весьма скупы на примеры, а для sax их вообще в оф. документации нет.

Это сообщение отредактировал(а) serghd - 29.1.2010, 20:23
PM MAIL   Вверх
LSD
Дата 1.2.2010, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Пока просто код без комментариев, через пару дней напишу статью в FAQ.
Код

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.*;

public class GeoIpParser
{
  private static final QName countryTagName = new QName("country");
  private static final QName ipStartAttribName = new QName("ip_start");
  private static final QName ipEndAttribName = new QName("ip_end");
  private static final QName flagAttribName = new QName("flag");

  private XMLInputFactory factory = XMLInputFactory.newInstance();
  private Attribute ipStart;
  private Attribute ipEnd;
  private Attribute flag;
  private StringBuilder chars = new StringBuilder();
  private boolean isInsideCountryTag = false;
  private List<GeoIPv4Adress> adresses;

  public static void main(String[] args)
  {
    GeoIpParser parser = new GeoIpParser();
    try
    {
      List<GeoIPv4Adress> geoIPv4AdressList = parser.parse(new File("xml/geo-ip.xml"));
      for(GeoIPv4Adress adress : geoIPv4AdressList)
      {
        System.out.println(adress);
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
  }

  public List<GeoIPv4Adress> parse(File file) throws IOException, XMLStreamException
  {
    FileInputStream in = new FileInputStream(file);
    XMLEventReader eventReader = factory.createXMLEventReader(in);

    adresses = new ArrayList<GeoIPv4Adress>();

    while(eventReader.hasNext())
    {
      XMLEvent xmlEvent = eventReader.nextEvent();
      switch(xmlEvent.getEventType())
      {
        case XMLStreamConstants.START_ELEMENT:
          processStartElement(xmlEvent.asStartElement());
          break;

        case XMLStreamConstants.CHARACTERS:
          processCharacters(xmlEvent.asCharacters());
          break;

        case XMLStreamConstants.END_ELEMENT:
          processEndElement(xmlEvent.asEndElement());
          break;
      }
    }

    List<GeoIPv4Adress> result = adresses;
    adresses = null;
    return result;
  }

  private void processStartElement(StartElement element)
  {
    if(element.getName().equals(countryTagName))
    {
      ipStart = element.getAttributeByName(ipStartAttribName);
      ipEnd = element.getAttributeByName(ipEndAttribName);
      flag = element.getAttributeByName(flagAttribName);
      isInsideCountryTag = true;
    }
  }

  private void processEndElement(EndElement element)
  {
    if(element.getName().equals(countryTagName))
    {
      createGeoIPv4Adress();

      ipStart = null;
      ipEnd = null;
      flag = null;
      chars.setLength(0);
      isInsideCountryTag = false;
    }
  }

  private void createGeoIPv4Adress()
  {
    try
    {
      adresses.add(GeoIPv4Adress.parse(ipStart.getValue(), ipEnd.getValue(), flag.getValue(), chars.toString()));
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
  }

  private void processCharacters(Characters characters)
  {
    if(isInsideCountryTag)
    {
      chars.append(characters.getData());
    }
  }
}

Код

package test;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * Created 01.02.2010 13:12:11
 *
 * @author $Id:$
 */
public class GeoIPv4Adress
{
  private static final int SIZE = 4;
  private static final long MASK = 0xFFFFFFFFL;

  private final int startAdress;
  private final int endAdress;
  private final String countryIsoCode;
  private final String countryName;

  public GeoIPv4Adress(int startAdress, int endAdress, String countryIsoCode, String countryName)
  {
    this.startAdress = startAdress;
    this.endAdress = endAdress;
    this.countryIsoCode = countryIsoCode;
    this.countryName = countryName;
  }

  public GeoIPv4Adress(byte[] startAdress, byte[] endAdress, String countryIsoCode, String countryName)
  {
    this(toInt(startAdress), toInt(endAdress), countryIsoCode, countryName);
  }

  public String getCountryIsoCode()
  {
    return countryIsoCode;
  }

  public String getCountryName()
  {
    return countryName;
  }

  public int getStartAsInt()
  {
    return startAdress;
  }

  public byte[] getStartAsBytes()
  {
    return toByteArray(startAdress);
  }

  public InetAddress getStartAsInetAddress() throws UnknownHostException
  {
    return InetAddress.getByAddress(getStartAsBytes());
  }

  public int getendAsInt()
  {
    return endAdress;
  }

  public byte[] getEndAsBytes()
  {
    return toByteArray(endAdress);
  }

  public InetAddress getEndAsInetAddress() throws UnknownHostException
  {
    return InetAddress.getByAddress(getEndAsBytes());
  }

  public boolean isInRange(final int ip)
  {
    long lip = MASK & ip;
    return ((startAdress & MASK) <= lip) && (lip >= (endAdress & MASK));
  }

  @Override
  public String toString()
  {
    StringBuilder buffer = new StringBuilder(getClass().getSimpleName()).append("[");

    buffer.append(countryName).append(" (").append(countryIsoCode).append("): ");

    byte[] bytes = getStartAsBytes();
    for(int i = 0; i < bytes.length; i++)
    {
      if(i > 0)
        buffer.append('.');
      buffer.append(Integer.toString(bytes[i] & 0xFF));
    }

    buffer.append(" - ");

    bytes = getEndAsBytes();
    for(int i = 0; i < bytes.length; i++)
    {
      if(i > 0)
        buffer.append('.');
      buffer.append(Integer.toString(bytes[i] & 0xFF));
    }

    buffer.append(']');
    return buffer.toString();
  }

  public static GeoIPv4Adress parse(String startIp, String endIp, String countryIsoCode, String countryName)
  {
    return new GeoIPv4Adress(parse(startIp), parse(endIp), countryIsoCode, countryName);
  }

  public static byte[] parse(String ip)
  {
    final String[] strings = ip.split("\\.");
    if(strings.length != SIZE)
      throw new IllegalArgumentException("Invalid input string - '" + ip + "'");

    byte[] bytes = new byte[SIZE];
    for(int i = 0; i < strings.length; i++)
    {
      String s = strings[i];
      int b = Integer.parseInt(s);
      if(b < 0 || b > 255)
        throw new IllegalArgumentException("Invalid input string - '" + ip + "'");

      bytes[i] = (byte) b;
    }
    return bytes;
  }

  private static byte[] toByteArray(final int i)
  {
    byte[] bytes = new byte[SIZE];
    bytes[0] = (byte) ((i >>> 24) & 0xFF);
    bytes[1] = (byte) ((i >>> 16) & 0xFF);
    bytes[2] = (byte) ((i >>> 8) & 0xFF);
    bytes[3] = (byte) (i & 0xFF);
    return bytes;
  }

  private static int toInt(final byte[] bytes)
  {
    if(bytes.length != SIZE)
      throw new IllegalArgumentException("Invalid array length, expected - 4, found - " + bytes.length);

    return ((bytes[0] & 0xFF) << 24) +
           ((bytes[1] & 0xFF) << 16) +
           ((bytes[2] & 0xFF) << 8) +
           (bytes[3] & 0xFF);
  }
}

Я немного изменил XML, убрал ненужные данные:
Код

<?xml version="1.0" encoding="UTF-8"?>
<countries>
  <country ip_start="2.6.190.56" ip_end="2.6.190.63" flag="GB">United Kingdom</country>
  <country ip_start="3.0.0.0" ip_end="4.17.135.31" flag="US">United States</country>
  <country ip_start="4.17.135.32" ip_end="4.17.135.63" flag="CA">Canada</country>
  <country ip_start="4.17.135.64" ip_end="4.17.142.255" flag="US">United States</country>
  <country ip_start="4.17.143.0" ip_end="4.17.143.15" flag="CA">Canada</country>
</countries>



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
serghd
Дата 2.2.2010, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



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

Это сообщение отредактировал(а) serghd - 2.2.2010, 15:11
PM MAIL   Вверх
LSD
Дата 2.2.2010, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(LSD @  1.2.2010,  20:58 Найти цитируемый пост)
через пару дней напишу статью в FAQ.

Готово..


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
sergioK
Дата 13.2.2010, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 15.2.2008

Репутация: нет
Всего: нет



[QUOTE=LSD,28.1.2010,  18:33]
Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
1. ArrayList когда у него заканчивается место в массиве (который используется для хранения) создает новый больше предыдущего в 1.5 раза, а потом копирует туда данные из старого.


Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
2. как в коде(не с помощью ключей) ее выделить?

Никак.



Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
3. как можно узнать объем объекта(не выделенной памяти)? в с++ есть оператор sizeof().

Честно - нет. А так создают много одинаковых объектов и смотрят, сколько они занимают места. Еще есть извраты через unsafe, рефлексию и т.д.



Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
4. равноправно ли правило, что строка состоящая из 10-ти символов занимает 10 байт памяти ВМ?

1. Один символ занимает 2 байта (это же Unicode).
2. Строка это объект и у нее есть еще данные кроме самих символов. Да и массив символов тоже потребляет место.
3. Строки могут совместно использовать массивы символов.
4. Некоторые ссылки на строку, могут быть ссылкой на одну и ту же строку.




Цитата(andrew_121 @  28.1.2010,  17:50 Найти цитируемый пост)
поясните пожалуйста. почему так?

Массив это объект. Как и любой объект у него есть накладные расходы: 8 байт на заголовок, 4 байта на длинну, и на данные. В случае с массивом объектов длинны 2 это будет 4*2 байта. Вот и считай, что лучше 2 * (8 + 4 + 75000 * 4) или (8 + 4 + 75000 * 4) + 75000 * (8 + 4 + 2* 4).

т,е , если было 1000 элеметов то выделит 1500,  перекопирует  потом  выделит 2250 , потом снова перекопирует и выделит  потом 3375 
 и т,д, 
откуда предположения что имеено в 1,5раза ,?  




PM MAIL   Вверх
jk1
Дата 13.2.2010, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Цитата

откуда предположения что имеено в 1,5раза?  

Исходники ArrayList это объясняют:
Код

 public boolean add(E e) {
    ensureCapacity(size + 1);  
    elementData[size++] = e;
    return true;
    }

Код

public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
         if (newCapacity < minCapacity)
        newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
    }
    }  


Это сообщение отредактировал(а) jk1 - 13.2.2010, 12:19


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
sergioK
Дата 13.2.2010, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 15.2.2008

Репутация: нет
Всего: нет



Цитата(jk1 @ 13.2.2010,  12:18)
Цитата

откуда предположения что имеено в 1,5раза?  

Исходники ArrayList это объясняют:
Код

 public boolean add(E e) {
    ensureCapacity(size + 1);  
    elementData[size++] = e;
    return true;
    }

Код

public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
         if (newCapacity < minCapacity)
        newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
    }
    }  

понятно, значит для решения подобных проблем связанных с нехваткой памяти ,  т,е, фактически нужно создать свой  мемory меnagment 
перегрузив ensureCapacity ,
 не увиличивать массив на 1,5 раза  (тотому что при больших размерах может таки выбить )а скажем добавлять 10 и до тех
пор пока не добавлены все 10 перекачку тоже делать не обязательно )

PM MAIL   Вверх
LSD
Дата 15.2.2010, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(sergioK @  13.2.2010,  19:48 Найти цитируемый пост)
не увиличивать массив на 1,5 раза  (тотому что при больших размерах может таки выбить )а скажем добавлять 10 и до тех
пор пока не добавлены все 10 перекачку тоже делать не обязательно )

И вместо 2,5 кратного потребления памяти получим ~2-х кратное. В общем выигрыш не велик smile

Если уж так хочется выжать память по максимуму, то стоит данные хранить не в одном массиве а в нескольких. Т.е. данные хранятся в нескольких маленьких массивах по паре килобайт. Пример реализации.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1761 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.