2011-02-05 3 views
1

У меня есть сервер командной строки на базе Java, на котором размещены рекорды для игры, которую я сделал на своем веб-сайте. Он работает эффективно и быстро. Однако это занимает около 200 МБ ОЗУ! Я пробовал все, от вручную обнулять все, называть System.gc() Java Game Server занимает слишком много памяти!

Я начинаю подозревать, что это может иметь что-то делать с потоком входных и выходных потоков объектов, которые я использую из гнезда подключения. Я заметил, что когда я впервые запускаю программу, она занимает обычное количество оперативной памяти. Затем, когда он получает соединение, он перескакивает до 100 МБ и продолжает получать больше для каждого соединения.

EDIT: В одном из моих классов я держу все имена, оценки и временную метку в трех разных ArrayLists. Однако тщательное обследование с использованием jhat и jmap показало, что в сочетании они используют только около 5 МБ ОЗУ.

Если это слишком расплывчато для любого, чтобы ответить, спросите, и я с радостью отправлю исходный код.

+2

Если вы видите, что он растет с каждым соединением и не падает, когда клиенты отключаются, вы, вероятно, поддерживаете ссылки на закрытые сокеты. – ide

+0

Если JVM - это что-то вроде .NET, то «заставить» сбор мусора не гарантируется на самом деле собирать что-либо, даже если есть неиспользуемые объекты, у которых нет ссылок на них. Кроме того, 200M - это арахис, когда вы можете купить 24 ГБ оперативной памяти за 300 $. Это действительно проблема? –

+0

@ide Это очень много растет с каждым подключением, а затем немного падает, поскольку они отключаются, так как я пытался вручную обнулить каждую ссылку на все объекты до того, как их жизнь закончится. – ra4king

ответ

3

У вас может быть утечка, вызванная сохранением ссылок на объекты, не относящиеся к их сроку службы.

Предлагаю вам получить профайлер и использовать его для расследования. Хорошим и свободным местом является программа VisualVM, распространяемая с Java 6.

Профайлер - это отдельная программа, которая либо подключается к JVM, либо размещает JVM для вашей программы и контролирует выполнение вашей программы. Он может отслеживать распределение объектов и выполнение кода, либо статистически, либо путем «инструментария» исполняемого кода. Он покажет вам, будут ли объекты выделены и не выпущены, и может показать, какие объекты они есть и где они были выделены (среди многих других полезных вещей).

Я использую jProfiler, который является коммерческим (но хорошо стоит для профессионала). В прошлый раз, когда я искал, было доступно несколько качественных профилировщиков (по крайней мере для личного использования). VisualVM имеет базовые, но полезные возможности профилирования, и я бы начал там (в Windows вы можете найти его в каталоге bin JDK, я полагаю, что то же самое верно для Linux и Mac).

+1

+1 за предложение профайлера –

+0

Что такое профайлер? – ra4king

+0

О, да, я раньше использовал профилировщик, я просто не знал, что он был вызван так: P Однако я никогда не использовал VisualVM, поэтому я буду исследовать его некоторое время. Спасибо! – ra4king

0

Попробуйте использовать что-то вроде jmap, за которым следует jhat, чтобы увидеть, как на самом деле используется ваша память.

JVM Sun (Oracle) никогда не выпускает память обратно в ОС, поэтому неудивительно, что вы видите монотонное увеличение использования памяти.

+0

jmap histogram option дал нормальные результаты, говоря, что в общей сложности около 25 МБ используемой памяти и почти 500 000 экземпляров. jmap dump с последующим jhat также показал нормальные результаты. – ra4king

+0

@Roi, я бы сказал, это свидетельствует о том, что у вас действительно нет проблемы, в зависимости от того, ожидаете ли вы, что существует полмиллиона объектов. (Не так ли? Если нет, пройдитесь по графику реферера в jhat.) Кстати, как вы оцениваете использование памяти? Вы смотрите на размер виртуальной памяти, выделенной для java, или смотрите размер его резидентного набора? – rlibby

+0

Я искал Частный рабочий набор в диспетчере задач – ra4king

Смежные вопросы