Ivan Babanin
Software Engineer
17 December 2016
16 December 2016
15 December 2016
Free and CoFree monads in Scala
http://underscore.io/blog/posts/2015/04/14/free-monads-are-simple.html
https://softwaremill.com/free-monads/
https://blog.scalac.io/2016/06/02/overview-of-free-monad-in-cats.html
http://typelevel.org/cats/datatypes/freemonad.html
http://degoes.net/articles/easy-monads
http://eed3si9n.com/herding-cats/stackless-scala-with-free-monads.html
http://blog.higher-order.com/assets/trampolines.pdf
https://softwaremill.com/free-monads/
https://blog.scalac.io/2016/06/02/overview-of-free-monad-in-cats.html
http://typelevel.org/cats/datatypes/freemonad.html
http://degoes.net/articles/easy-monads
http://eed3si9n.com/herding-cats/stackless-scala-with-free-monads.html
http://blog.higher-order.com/assets/trampolines.pdf
16 April 2015
PrintAssembly in Intel syntax
By default -XX:+PrintAssembly prints Assembly in AT&T syntax (used in GAS). Intel syntax available with -XX:PrintAssemblyOptions=intel. BTW another options available using -XX:PrintAssemblyOptions=hsdis-help.
05 February 2015
27 January 2015
Производительность ArrayList.toArray(...)
Another VM performance puzzler, ArrayList.toArray(...) performance:
http://t.co/3w7msVykwK
/cc @twillouer
— Aleksey Shipilëv (@shipilev) January 24, 2015
Копия бенчмарка тут.
Если вкратце, то:
- ArrayList.toArray() - самый быстрый, так как создается Object[], а далее происходит копирование с помощью векторной инструкции AVX. Никаких проверок на совместимость типов.
- ArrayList.toArray(new T[size]) - намного медленнее чем toArray(), так как здесь копирование происходит поэлементно из за проверки типов.
- ArrayList.toArray(new T[0]) - что самое интересное быстрее, чем если бы мы передали преалоцированный массив нужного размера toArray(new T[size]). Причиной этому является тот факт, что когда мы передаем готовый массив, то JVM необходимо проинициализировать его null'овыми значениями (иначе говоря, обнулить). В случае когда мы передаем массив нулевого размера, то JVM сама создаст массив нужно размера и заполнит элементами из ArrayList, таким образом его не придется "обнулять".
02 February 2014
SQLDeveloper 4 crash JVM on startup
New SQLDeveloper 4 crashes on Ubuntu 13.10 and JDK 1.7.0_45:
Solution is simple, before launch sh sqldeveloper.sh unset environment variable GNOME_DESKTOP_SESSION_ID or you can create another launcher.sh like this:
and just invoke sh launcher.sh.
Solution is simple, before launch sh sqldeveloper.sh unset environment variable GNOME_DESKTOP_SESSION_ID or you can create another launcher.sh like this:
and just invoke sh launcher.sh.
03 December 2013
Integer cache
Есть такая известная задачка, что напечатает в консоль данный код:
Казалось бы очевидно - везде '127', но не все так просто. В Java для оптимизации числа объектов был разработан так называемый Integer cache (некий аналог String pool):
Аналогичный кэш существует и для оберток типа Long:
По-умолчанию размер кэша - 256 и заполнен числами в интервале [-128; 127]. Но размер можно изменить:
Таким образом, мы значение '127' заменяем на '0' и код, приведенный в начале, в 1-ом и 3-ем случае выведет '0'! В 1-ом случае мы выводим измененный объект 'x', во 2-ом - будет вызван метод println(int x) и боксинг не произойдет, в 3-ем случае произойдет боксинг и возьмется значение из кэша, в 4-ом - мы явно создаем объект в обход кэша.
Такие дела,
Иван
Казалось бы очевидно - везде '127', но не все так просто. В Java для оптимизации числа объектов был разработан так называемый Integer cache (некий аналог String pool):
Аналогичный кэш существует и для оберток типа Long:
По-умолчанию размер кэша - 256 и заполнен числами в интервале [-128; 127]. Но размер можно изменить:
- -XX:AutoBoxCacheMax=XXXX - увеличивает размер кэшей (Integer, Long) до XXXX + 128, где будут храниться значения в интервале [-128; XXXX];
- -XX:+AggressiveOpts - опция изменяет значения множества опций, среди которых увеличивает AutoBoxCacheMax до 20 000;
- -Djava.lang.Integer.IntegerCache.high=XXXX - данная опция по аналогии с AutoBoxCacheMax увеличивает размер кэша, только в данном случае только для объектов типа Integer.
Таким образом, мы значение '127' заменяем на '0' и код, приведенный в начале, в 1-ом и 3-ем случае выведет '0'! В 1-ом случае мы выводим измененный объект 'x', во 2-ом - будет вызван метод println(int x) и боксинг не произойдет, в 3-ем случае произойдет боксинг и возьмется значение из кэша, в 4-ом - мы явно создаем объект в обход кэша.
Такие дела,
Иван
08 October 2013
Утилиты в составе JDK / Standard JDK utilities
В составе JDK, помимо всем известных javac, java, есть ещё несколько полезных утилит:
jconsole.exe 16,776
Утилита позволяющая узнать конфигурацию запущенной JVM (для этого в параметрах нужно указать ID процесса): версию JVM, системные параметры, флаги.
Утилита показывающая список объектов разделяемой памяти (shared object memory), либо объектов находящихся в heap'е. Для запуска утилиты необходимо указать ID процесса. В зависимости от параметров возможно получение следующей информации:
Утилита печатающая все стэктрэйсы (stacktrace) JVM запущенной локально (необходимо указать ID процесса), либо удаленно (< ID процесса >@< IP адрес системы на которой запущена JVM >). Если утилита запущена с параметром -m (mixed mode), то также выводится стэктрэйс нативных методов.
Утилита позволяющая декомпилировать class-файл. В качестве параметра необходимо указать путь к файлу класса. В зависимости от параметров возможно получение следующей информации:
Утилита позволяющая анализировать heap дампы через веб интерфейс и DSL OQL (Object Query Language) (SQL-подобный язык запросов) . Дамп для анализа можно получить одним из следующих способов:
Такие дела,
Иван.
Имя утилиты Размер (байт)
jconsole.exe 16,776
jinfo.exe
16,264
jmap.exe
16,264
jstack.exe
16,264
javap.exe
15,752
jhat.exe
15,752
jps.exe
15,752
jstat.exe
15,752
Я не случайно привел размер каждой утилиты, так как он практически у всех идентичный (~16-17 Кб). По факту, каждая из утилит реализована на Java, а в момент сборки в качестве шаблона используется простейшая утилита реализованная на языке C, которая ищет JRE, затем парсит аргументы, создает JVM, ищет Java-класс утилиты и вызывает соответствующий метод main. Исходной код можно найти здесь (${JDK_SOURCE}/jdk/src/share/classes/sun/ или ${JDK_SOURCE}/langtools/src/share/classes/com/sun/tools/).
Любую из утилит можно использовать в своем приложении. Для этого необходимо в classpath добавить библиотеку tools.jar (${JDK_DIR}/lib/tools.jar).
Любую из утилит можно использовать в своем приложении. Для этого необходимо в classpath добавить библиотеку tools.jar (${JDK_DIR}/lib/tools.jar).
Рассмотрим самые наиболее популярные из них.
Утилита показывающая список JVM (в формате < ID процесса > < Main класс >) запущенных локально или удаленно (для этого необходимо в параметрах хост удаленной системы).
Графическая утилита для мониторинга JVM запущенной на локальной или удаленной системе. JConsole использует расширенные возможности JVM и предоставляет информацию касательно производительности, потребляемой памяти, потоков приложения, загруженных классов. Запустить утилиту можно из командной строки введя команду jconsole (появится диалоговое окно выбора JVM для мониторинга), также в качестве параметров можно указать ID процесса (если JVM запущена локально) или имя хоста и порт (если JVM запущена удаленно).
jps
(sun.tools.jps.Jps)Утилита показывающая список JVM (в формате < ID процесса > < Main класс >) запущенных локально или удаленно (для этого необходимо в параметрах хост удаленной системы).
jconsole
(sun.tools.jconsole.JConsole)Графическая утилита для мониторинга JVM запущенной на локальной или удаленной системе. JConsole использует расширенные возможности JVM и предоставляет информацию касательно производительности, потребляемой памяти, потоков приложения, загруженных классов. Запустить утилиту можно из командной строки введя команду jconsole (появится диалоговое окно выбора JVM для мониторинга), также в качестве параметров можно указать ID процесса (если JVM запущена локально) или имя хоста и порт (если JVM запущена удаленно).
jinfo
(sun.tools.jinfo.JInfo)Утилита позволяющая узнать конфигурацию запущенной JVM (для этого в параметрах нужно указать ID процесса): версию JVM, системные параметры, флаги.
jmap
(sun.tools.jmap.JMap)Утилита показывающая список объектов разделяемой памяти (shared object memory), либо объектов находящихся в heap'е. Для запуска утилиты необходимо указать ID процесса. В зависимости от параметров возможно получение следующей информации:
- Если нет дополнительных аргументов, то выводится список объектов разделяемой памяти. Для каждого объекта указывается стартовый адрес, размер маппинга и полный путь до файла данного объекта.
- -dump:format=b,file=< путь к файлу для дампа > - создается дамп heap'a в бинарном формате hprof. Для того чтобы просмотреть объекты находящиеся в дампе можно воспользоваться стандартной утилитой jhat (будет рассмотрена далее), либо использовать более удобное средство - Eclipse Memory Analyzer.
- -finalizerinfo - выводит список объектов ожидающих финализацию (finalization).
- -histo - выводит гистограмму объектов находящихся в heap'e. Для каждого класса выводится информация о количестве объектов, размере используемой памяти.
- -permstat - выводит расширенную статистику по загрузчикам классов (class loader). Для каждого загрузчика классов выводится его имя, адрес, родительский загрузчик классов (parent class loader), количество и размер загруженных классов.
jstack
(sun.tools.jstack.JStack)Утилита печатающая все стэктрэйсы (stacktrace) JVM запущенной локально (необходимо указать ID процесса), либо удаленно (< ID процесса >@< IP адрес системы на которой запущена JVM >). Если утилита запущена с параметром -m (mixed mode), то также выводится стэктрэйс нативных методов.
javap
(com.sun.tools.javap.Main)Утилита позволяющая декомпилировать class-файл. В качестве параметра необходимо указать путь к файлу класса. В зависимости от параметров возможно получение следующей информации:
- Если нет дополнительных параметров, то выводится информация о пакете класса (package), родительский класс, список методов и их сигнатуры.
- -c - В дополнении к базовой информации о классе, выводится список байткодов.
- -verbose - Выводит информацию о размере стека, количестве локальных переменных и аргументов.
Из всех параметров самый важный это verbose - с помощью него можно получить практически всю информацию о классе.
jhat
(com.sun.tools.hat.Main)Утилита позволяющая анализировать heap дампы через веб интерфейс и DSL OQL (Object Query Language) (SQL-подобный язык запросов) . Дамп для анализа можно получить одним из следующих способов:
- Использовать утилиту jmap (была описана ранее);
- С помощью утилиты jconsole (была описана ранее) можно получить дамп используя MBean HotSpotDiagnosticMXBean;
- Дамп будет сгенерирован в случае возникнования OutOfMemory и при этому у JVM была указана опция -XX:+HeapDumpOnOutOfMemoryError;
- Использовать утилиту hprof.
Помимо самого дамп файла, в качестве параметров можно указать порт для веб интерфейса (по умолчанию 7000).
jstat
(sun.tools.jstat.Jstat)Такие дела,
Иван.
29 August 2013
Array initialization
Java class file stores array initializers as a sequence of explicit array-element initializers, equivalent to data[0]=1, data[1]=2; data[2]=3; instead of comcact block of packed bytes.
19 August 2013
JVM internals: Runtime data areas
When a Java virtual machine runs a program, it needs memory to store many things, including bytecodes and other information it extracts from loaded class files, objects the program instantiates, parameters to methods, return values, local variables, and intermediate results of computations. The Java virtual machine organizes the memory it needs to execute a program into several runtime data areas.
Overview of all data areas:
Overview of all data areas:
Let's talk about each one in detail.
Data areas individual for each thread:
- The pc Register - program counter register. Each JVM thread has its own pc register. At any time JVM thread executing method and if that method is not native, the pc register contains the address (in Method Area) of next instruction to execute, but is method is native then pc register's value is undefined.
- Stack. JVM stack stores the state of each Java (not native) method invocations for the thread. State of method invocation placed in stack frame (or simply frame), so then thread invokes method, new frame created and pushed to stack, and then method completes frame poped and discarded from virtual machine. State of frame contains local variables, parameters of method, return result, intermediate calculations also know as operand stack (as JVM is stack-based VM, it has no registers to store intermediate calculations) and reference to current class constant pool. The sizes of local variable array and the operand stack are determined at compile-time. Only one frame is active at any point of thread execution and this frame is called current frame and it's method known as current method. It should be mention, the memory for JVM stack doesn't have to be contiguous.
- Native Method Stack. Native method stack also called as "C stack". Native method stack is used for native method invocation and also may be used by the implementation of a JVM bytecode interpreter.
Interaction between Java stack and Native Method Stack:
Data areas shared by all threads:
- Heap.
- Method Area. Method area is used to store per-class structures such as
runtime constant pool, field and method data, code for methods and constructors
(including special methods used in class or object initialization). Method area
is created on virtual machine start up and it is logical part of heap. JVM
provide control over minimum and maximum size of method area or just initial
size.
- Runtime Constant Pool. Runtime constant pool is per-class or per-interface runtime
representation of the constant_pool table in a class file. It contains several
kinds of constants ranging from literal constants known at compile time to method
and field references resolved at runtime. Runtime constant pool is constructed
when class or interface created in virtual machine.In class file constant pool is represented as array of structures like:
constant_info {
u1 tag;u1 info[];}
Tag is 1 byte value which is vary from 1 to 18 and represents one of constant type.
· CONSTANT_Utf8 (1)
u1 tag – constant type (1)u2 length – number of bytes in byte arrayu1 bytes[length] – contains bytes of string (byte value > 0 i. e. in range (0; 0x0F)) (strings is encode in modified UTF-8)
· CONSTANT_Class (7)
tag - constant type (7)name_index - index of CONSTANT_Utf8 entry in constant_pool
· CONSTANT_FieldRef (9)
· CONSTANT_MethodRef (10)
· CONSTANT_InterfaceMethodRef (11)
u1 tag – constant typeu2 class _index – index of CONSTANT_Class entry in constant poolu2 name_index – index of CONSTANT_NameAndType entry in constant pool
· CONSTANT_String (8)
u1 tag – constant type (8)u2 string_index – index of CONSTANT_Utf8 entry in constant pool to which the String object is to be initialized
· CONSTANT_Integer (3)
· CONSTANT_Float (4)
u1 tag – constant typeu4 bytes – value of constant in bytes in big-endian order (high order first)
· CONSTANT_Long (5)
· CONSTANT_Double (6)
u1 – constant typeu4 hight_bytesu4 low_bytesVALUE = ((long) high_bytes << 32) + low_bytes
· CONSTANT_NameAndType (12)
u1 tag – constant typeu2 name_index – method or field nameu2 descriptor_index – method or field descriptorField descriptor –§ B – byte§ C – char§ D – double§ F – float§ I – integer§ J – long§ L ClassName ; - reference§ S – short§ Z – Boolean§ [ - array dimension (one bracket per dimension)Method descriptor – (FieldDescriptor*)ReturnDecriptor (return descriptor may be V – void or FieldDescriptor)
· CONSTANT_MethodHandle (15)
u1 tag – constant typeu1 reference_kind – value denotes the kind of method handle, which characterizes its bytecode behavior and lies in range 1 to 91. REF_getField + CONSTANT_Field2. REF_getStatic + CONSTANT_Field3. REF_putField + CONSTANT_Field4. REF_putStatic + CONSTANT_Field5. REF_invokeVirtual + CONSTANT_MethodRef (all methods excludingand ) 6. REF_invokeStatic + CONSTANT_MethodRef (all methods excludingand ) 7. REF_invokeSpecial + CONSTANT_MethodRef (all methods excludingand ) 8. REF_newInvokeSpecial + CONSTANT_MethodRef (only) 9. REF_invokeInterface + CONSTANT_InterfaceMethodRef (all methods excludingand ) u2 reference_index – value of CONSTANT_Field, _MethodRef, _InterfaceMethodRef
· CONSTANT_MethodType (16)
u1 tag – constant typeu2 descriptor_index – valid index of CONSTANT_Utf8 entry in constant_pool which representing a method descriptor
· CONSTANT_InvokeDynamic (18)
u1 tag – constant typeu2 bootstrap_method_attr_index – valid index of bootstrap_methods array of the bootstrap method table of current class fileu2 name_and_type_index – valid index of CONSTANT_NameAndType entry in constant_pool representing method name and method descriptor
JVM internals: VM types
Like the Java programming language JVM operated two kinds of types: primitive and reference types.
All type checking performed by compiler, and does not have to be done by JVM.
VM primitive data types:
All type checking performed by compiler, and does not have to be done by JVM.
VM primitive data types:
- numeric
- byte - 8-bit signed / [-128;127];
- short - 16-bit signed [-32768; 32767];
- char - 16-bit unsigned [0; 65535];
- int - 32-bit signed [-2147483648; 2147483647];
- float - 32-bit precision (IEEE 754 standard);
- long - 64-bit signed [-;];
- double - 64-bit precision (IEEE 754 standard).
- boolean - JVM provides limited support to boolean data type. There are no VM instructions solely dedicated to operation on boolean type. Expressions to operate boolean type are compiled to use int data type (int value 1 - true, int value 0 - false). JVM directly supports boolean arrays as byte arrays (so it using 8 bytes per boolean value and bytecode instructions that are also suitable for byte arrays):
- newarray - creates boolean array;
- baload - access to boolean array;
- bastore - modify boolean array.
- returnAddress - returns pointer to the opcodes of JVM instructions. The data type used by JVM instructions: jsr, jsr_w, ret. Anlilke other JVM datatypes, returnAddress doesn't correspond to any Java programming language type and cannot be modified by running program.
VM reference types:
- class types;
- interface types;
- array types.
A VM reference may be null reference - reference to no object and default value of any reference. Null reference initialy in runtime has no type, but may be cast to any reference type.
Subscribe to:
Posts (Atom)