Category: it

Category was added automatically. Read all entries about "it".

JVM изнутри – организация памяти внутри процесса Java

Наверное, все, работающие с Java, знают об управлении памяти на уровне, что для ее распределения используется сборщик мусора. Не все, к сожалению, знают, как именно этот сборщик (-и) работает, и как именно организована память внутри процесса Java.


Из-за этого иногда делается неверный вывод, что memory leaks в Java не бывает, и слишком задумываться о памяти не надо. Так же часто идут холивары по поводу чрезмерного расхода памяти.
Все описанное далее относится к Sun-овской реализации JVM (HotSpot), версий 5.0+, конкретные детали и алгоритмы могут различаться для разных версий.

Итак, память процесса различается на heap (куча) и non-heap (стек) память, и состоит из 5 областей (memory pools, memory spaces):
• Eden Space (heap) – в этой области выделятся память под все создаваемые из программы объекты. Большая часть объектов живет недолго (итераторы, временные объекты, используемые внутри методов и т.п.), и удаляются при выполнении сборок мусора это области памяти, не перемещаются в другие области памяти. Когда данная область заполняется (т.е. количество выделенной памяти в этой области превышает некоторый заданный процент), GC выполняет быструю (minor collection) сборку мусора. По сравнению с полной сборкой мусора она занимает мало времени, и затрагивает только эту область памяти — очищает от устаревших объектов Eden Space и перемещает выжившие объекты в следующую область.
• Survivor Space (heap) – сюда перемещаются объекты из предыдущей, после того, как они пережили хотя бы одну сборку мусора. Время от времени долгоживущие объекты из этой области перемещаются в Tenured Space.
• Tenured (Old) Generation (heap) — Здесь скапливаются долгоживущие объекты (крупные высокоуровневые объекты, синглтоны, менеджеры ресурсов и проч.). Когда заполняется эта область, выполняется полная сборка мусора (full, major collection), которая обрабатывает все созданные JVM объекты.
• Permanent Generation (non-heap) – Здесь хранится метаинформация, используемая JVM (используемые классы, методы и т.п.). В частноси
• Code Cache (non-heap) — эта область используется JVM, когда включена JIT-компиляция, в ней кешируется скомпилированный платформенно — зависимый код.

Вот тут — blogs.sun.com/vmrobot/entry/основы_сборки_мусора_в_hotspot есть хорошее описание работы сборщиков мусора, перепечатывать не вижу смысла, советую всем интересующимся ознакомиться подробней по ссылке.

Oracle - insufficient privileges внутри хранимой процедуры

Немного об одной тонкости в системе привилегий Oracle, о которой не все знают, и которая может съесть немало времени на отладку.

Суть в следующем --
Для хранимых процедур, триггеров и прочего PL/SQL (но НЕ для анонимных блоков PL/SQL!) привилегии, необходимые для выполения команд динамического SQL (например, execute immediate ('create synonym s1 for table_1')) должны быть даны создателю (тому пользователю, в схеме которого выполняется процедура или триггер) явно, а не через роль. Очень важный момент, речь идет не о привилегии на выполнение процедуры, а о привилегиях, необходимых для выполнения команд динамического SQL.

Подробности тут - www.sql.ru/faq/faq_topic.aspx

Советую разобраться со всеми примерами, это та вещь, которую сложновато бывает отладить без знания того, что происходит внутри.

Сайт Intuit.ru и его тесты

Сдал для получения автомата по базам данных в универе тесты на Intuil.ru по MySQL и по прологу.
Тесты сами по себе -- фигня, проходятся с базовым знанием предмета и сильно развитым скилом гугления за час от силы каждый. Зато диплом - симпатичный :)
Не удержусь и дам ссылки (кликабельно):

Диплом Интернет-Университета Информационных Технологий: Введение в СУБД MySQL


Диплом Интернет-Университета Информационных Технологий: Основы программирования на языке Пролог

Java Unsafe

Во время обзора декомпиляторов натолкнулся я на несколько изумительных статей на wasm.ru -
wasm.ru/article.php - Unsafe Java (часть 1) и
wasm.ru/article.php - соответственно  часть два.
Описывают, что такое Unsafe api, предоставляющее программисту возможность работать с классами, методами и т.п. ниже того уровня , который позволяют штатные средства платформы Java - на фактически на уровне тех самых С-структур, которые используются внутри JVM для предоставления сущностей класс, инстанс класса, метод и т.п.
Что дает возможность делать многие вещи, которые в программировании на Java как бы "традиционно" считаются невыполнимыми - функция sizeOf, (возвращаются точный размер объекта в памяти , взятый напрямую из поля  структуры, которая представляет этот объект на уровне JVM), наследования от final-класса (делается двумя шагами по сути -  в список предков класса добавляется нужный нам класс, и из таблицы модификаторов доступа для этого суперкласса во время выполнения программы удаляется final - всего делов ;) ).

Ну и уже более изощренные и хакерские штучки - самомодицирующиеся во время выполнения методы..и т.п. Очень рекомендую эти статьи к прочтению :).
Да, конечно -- смещения полей в структурах высчитываются на пальцах, класс sun.mics.Unsafe недокументирован (но присутствует в Java с самого ее начала, и очень навряд ли будет из нее удален - я очень сильно подозреваю, что предоставляемые им низкоуровневые возможности используются инструментами типа отладчиков и т.п.), и в продакшне ни один Project Manager такое использоватьне позволит -- да и не требуется в обычных приложения никогда столь низкоуровневый доступ к JVM. Но знать, как ява-машины работает с классами внутри себя -- полезно и интересно, а знать что из обычной программы на чистой яве можно получать доступ такого уровня -- еще интересней.

И напоследок два слова по поводу того, что это gap в ява-машине, который будет закрыт в следующем же релизе и т.п.
Я не думаю, что это дыра в системе безопасности Java.
Собственно, суммирую и повторю описанное в первой из статей.
Итак. Есть две точки входа для получения инстанса класса Unsafe, который позволит нам творить черную магию:
1) Получить его можно через Unsage.getUnsafe() - НО! только в том случае, если вызывающий класс был загружен первичным класслоадером (www.tedneward.com/files/Papers/BootClasspath /BootClasspath.pdf - тут можно прочитать подробней про иерархию класслоадеров). Это сделать несложно -- всего-то добавить ключ -Xbootclasspath в список стартовых опций ява-машины. Но для этого надо иметь доступ  к среде выполнения.
2) Можно просто взять private переменную theUnsafe - которая хранит инстанс класса Unsafe внутри него. Но если есть Security Manager и установлена для него соответствующая политика запрещения опасной рефлексии , получить значение этой закрытой переменной не удастся.
Соответственно, мой вывод -- это API не является уязвимостью в JVM, вовсе нет.
Потому что точно так же рефлексией (если она не запрещена в политиках безопасности) можно творить безобразия внутри приложения, но и польза от нее может быть большая-- надо просто разумно выставлять политики безопасности в каждом конкретном случае.
Да - Unsafe API дает беспрецедентный уровень доступа к среде выполнения Java из программы. Но чтобы получить доступ к этому апи -- надо либо иметь соотв. права на той машине, где выполняется приложение (например, возможность задавать параметры запуска ява-машины), либо должен быть соответственно сконфигурирован (без учета этой опасности) Security Manager.

Надеюсь, кому-то было интересно это прочитать :)

 

Java Decompilers

Помню, на  forum.juga.ru один очень уважаемый там человек когда-то жаловался, что многие люди пытаются запустить .java файл, и ругаются что не работает. Шутки шутками -  как итог  на многих форумах есть в FAQ описание для новичков, как взять .java файл и скомпилировать его в .class файл.
При этом, я не припоминаю чтобы где видел описание обратного процесса -- как получить из .class файла .java файл.

Настало время сделать обзор полезный и интересных инструментов для программиста - декомпиляторов :).

Кто-то скажет, что  прежде всего надо разобраться, как устроен этот самый файл, прочитать его спецификацию, узнать как он процессится ява-машиной и т.п., но это уже just for fun или для профессионалов в области разработки инструментария в этой области. Я сам сторонник фундаментальности, однако современные декомпиляторы позволяют работать с .class файлами без предварительного изучения их структуры, кто считает полезным прочитать спецификацию формата .class -  http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html.  Сам считаю, что знать ее для серьезного ява программиста -- очень желательно, но пользоваться в повседневных задачах декомпилятором можно и без этого знания.

Итак, из  чтения пары статей на форумах, общения с некоторыми знакомыми кофейниками, пары часов в гугле, и собственного скромного опыта декомпилирования ява-приложений родилось:

А, вот интересная статья по этому поводу -
http://www.program-transformation.org/Transform/JavaDecompilers
Читать всем :)

Итак:

1. Java Decompiler - http://java.decompiler.free.fr/.
Очень простой, понятный интерфейс, запускаем, открываем .class файл (а так же можно открывать и .jar файлы, мелочь а приятно. При открытии джарника можно развертывать иерархию пакетов и смотреть исходный код классов, а вот манифест и ресурсы -- почему то нет, что немного обидно), и на экране желаемый сорскод.
Качество движка - спорное. С одной стороны, в моих тестах грамотно распознал рекурсию и аннотации, с другой -  времени от времени тупил, создавая некомпилирующийся код в простых случаях, вроде -

вместо
int count = 2, 
создавал:
int count;
int count = 2; // compilation error, var. already exists.

В целом -- ничего, неплохо.

2.  DJ Java Decompiler.
Выглядит серьезней, кроме декомпиляции поддерживает так же дизассемблирование, просмотр более полной информации о версии класса, его членах и их  аттрибутах,  пула констант, просмотр шестнадцетиричных кодов (специально для извращенцев  истинных ценителей) и многое другое.
По сути - фронтэнд к очень популярному, но имхо, несколько староватому движку декомпиляции Jad.

Более того -- почти все современные серьезные дизассемблеры, как прошлых лет, так и сегодняшние, используют этот движок :).

Чтобы не быть голословным --  вот список продуктов, являющихся по сути фрондэндом Jad:
FrontEnd Plus -
http://www.reflectonus.pwp.blueyonder.co.uk/download.htm [02/29/2004: page not found]

NMI's Java Code Viewer -
http://www.trinnion.com/javacodeviewer [02/29/2004: Discontinued]

Decafe Pro -
http://decafe.hypermart.net

mDeJava -
http://molesoftware.hypermart.net [02/29/2004: site not found]

FrontJad -
http://www.ire.pw.edu.pl/~mszklan/frontjad.htm [02/29/2004: page not found]

DJ Java Decompiler -
http://members.fortunecity.com/neshkov/dj.html

Cavaj Java Decompiler -
http://www.bysoft.se/sureshot/cavaj

JavaDecompiler -
http://iago-soft.iespana.es/iago-soft/jdecompiler/jdecompiler.htm (in Spanish) [02/29/2004: page not found]

JadClipse, Jad plugin for Eclipse IDE -
http://sourceforge.net/projects/jadclipse

decompile.zip - an add-on to the Java Development Environment (JDE) for GNU Emacs. It automatically decompiles a class file and offers you a buffer to view or edit it. The add-on is written and maintained by Ingo Koch (ingo.koch@ikoch.de).

VajDecompiler -
http://www.ibldesign.com/lorin/VAJDecompiler.shtml - Jad frontend for VisualAge for Java

decomp.zip - yet another LISP code for Emacs that runs Jad on the current buffer. Contributed by R. Mecklenburg.

jadAlign v1.01 is an utility created by Bernard Poulin (bernard@acm.org) that re-alignes Java source files produced by Jad. The resulting file can then be used for source-level debugging (i.e. stepping in the code). The size of the archive is 20942 bytes.

JADClassFileNode - an open tool by A. Sazonov that replaces the built-in decompiler in JBuilder.

JASM - Java disassembler module for NetBeans IDE.

JavaDecompiler.vim - plugin for VIM editor by David Bowers.


3. Cavaj Java Decompiler. Видимо авторы были заядлыми анимешниками, иначе откуда могло взяться  такое название :). 
Бросающаяся в глаза неприятная мелочь --  в диалоге открытия файла для декомпиляции нету фильтра по типам .class, .jar и т.п. Мелочь -- а раздражает.
Поскольку движок декомпиляции тот же самый, то тут комментировать особо нечего.
В интерерфейсе никаких вкусносней нет и в помине, подсветки полученного java-code нету, байткод посмотреть тоже нельзя. Мне не понравился.

Итог - DJ на мой взгляд, лучший из декомпиляторов Java на сегодняшний день.













Запуск Java приложений в виде сервисов

Недавно на работе возникла необходимость запустить сервер приложений JBoss в виде
Windows NT service.
Найдено было два способа, дам ссылки на оба, может кому пригодится.
Первый из них подходит только для JBoss, зато второй гораздо более общий -- с его помощью можно запускать в виде сервисов любое Javа-приложение, причем с кучей дополнительных возможностей, (и, конечно, под любой осью).

Оба способа описаны тут - http://wiki.jboss.org/wiki/RunJBossAsAServiceOnWindows.

Итак, для первого способа -- качаем билд JBossNative под свою ось,  как указано в инструкции, и читаем readme-service для инструкций :)

http://wiki.jboss.org/wiki/JBossNativeWindows -- или смотрим их здесь.  Этим способом JBoss ставится действительно одной командой с консоли:
C:\> cd c:\jboss-4.2.0\bin
C:\> service.bat install
А теперь чуть подробней про второй способ. Прежде всего -- он не совсем бесплатный, бесплатен он для open-source и продуктов, лицензированных иным способом, но от которых вы не получаете дохода. В двух словах так, но советую внимательней прочитать лицензию. Идем на сайт производителя Java Service Wrapper тула - http://wrapper.tanukisoftware.org/. Качаем архив (я советую скачивать архив только под родную ОС), дальше действуем как описано в самой первой ссылке этого поста. Расписано все понятно, и собственно заводится и работает все без танцев с бубном, но есть пара неочевидных моментов, про которые я сейчас скажу и которые отняли у меня время. Во-первых, советую просмотреть сразу все свойства файла конфигурации - http://wrapper.tanukisoftware.org/doc/english/properties.html. Чтоб знать что и как можно делать. Не забываем про установку нужных -Dname=value свойств для передачи значений JVM. И еще -- иногда хотелось бы запускать сервер в interactive-mode, чтобы при его старте открывалась консоль. Сделать это можно следующим образом - добавьте в конфиг враппера строчки wrapper.ntservice.console=true
wrapper.ntservice.interactive=true.

Но учтите - 
 Desktops created with the Remote Desktop tool do not appear to ever be
 accessible by interactive services.  Other tools which are actually 
 mirroring the  local desktop will have access as Windows thinks it is 
 rendering the local desktop. 
Ну и напоследок - коротко о фичах.
Можно составлять файл комманд, которые должны выполняться в определенное время, и указать
его в файле конфигурации враппера. Шедулинг работает нормально.
Можно писать хэндлеры консольного вывода, которые могут, например, перезапускать сервис, когда
падает некоторая ошибка (например, OufOfMemoryError).
Можно настраивать нотификацию администраторам на email.
...

Всем спасибо за внимание :)
Надеюсь, профессионалам Java это окажется небесполезным.