26 Şubat 2019 Salı

Collector Arayüzü

Giriş
Java 8 ile gelen Stream kütüphanesindeki collect() metodu içine bir Collector alır. Collector nesnesini üretmek için hazır gelen gibi metodları kullanmak çok daha kolay.
Collectors.toList();
Arayüz Parametreleri
Collector arayüzü şöyle tanımlıdır. T reduction işlemine giren nesneyi, A işlem sonucunda çıkan biriktirilmiş nesneyi (accumulation type), R reduction işleminin sonucunu belirtir.
public interface Collector<T, A, R> {
    Supplier<A> supplier();
    BiConsumer<A, T> accumulator();
    BinaryOperator<A> combiner();
    Function<A, R> finisher();
}
collectingAndThen metodu
Composed Collector yazmak için kullanılır.

of metodu Niye Lazım
Collector.of() metodu yazısına taşıdımç

DoubleStream Arayüzü

Giriş
Şu satırı dahil ederiz.
import java.util.stream.DoubleStream;
JDK'da FloatStream diye bir sınıf yok!

average metodu
Şöyle yaparız.
double[] x = {5.4, 5.56, 1.0};
double avg = Arrays.stream(x).average.getAsDouble ();
collect metodu
Bu metod Stream arayüzünden farklı olarak Collector parametresi almaz. İmzası şöyle
R collect(Supplier<R>, ObjDoubleConsumer<R>, BiConsumer<R,R>)
iterate metodu
Şöyle yaparız.
double[] sequence = DoubleStream.iterate(200.0, d -> d + 0.001)
  .limit((int) (1 + (399.999 - 200.0) / 0.001)).toArray();
min metodu
Bir OptionalDouble döner. OptionalDouble sınıfının getAsDouble metodu ile değeri alırız. Şöyle yaparız.
double min = DoubleStream.of(array).parallel().min().getAsDouble();
sum metodu
Açıklaması şöyle
In particular, this method may be implemented using compensated summation or other technique to reduce the error bound in the numerical sum compared to a simple summation of double values.
Şöyle yaparız.
Double sum = DoubleStream.builder().add(0.1).add(0.1).add(0.1).add(0.1).add(0.1)
  .add(0.1).add(0.1).add(0.1).add(0.1).add(0.1).build().sum();
System.out.println(sum);
Çıktı olarak 1.0 alırız.
Bu toplama işlemi Kahan summation kullandığı için şu koddan daha az hatay sebep olur.
System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);
Çıktı olarak 0.9999999999999999 alırız.

IntelliJ Idea

Lisans
Pahalı olduğu için 2021.1 sürümüne kadar evaluation license silerek idare edilebilir. Daha sonraki sürümlerde çalışmıyor. 

Bence önce buraya bakarak bir reset.bat yazdım. reset.bat dosyasında şöyle yaparız
@echo off
REM Delete eval folder with licence key and options.xml which contains a reference to it
FOR %%I IN ("WebStorm", "IntelliJ", "CLion", "Rider", "GoLand", "PhpStorm", "Resharper", "PyCharm") DO (
  FOR /d %%a IN ("%APPDATA%\JetBrains\%%I*") DO (
    rd /s /q "%%a/eval"
    REM del /q "%%a\options\other.xml"
  )
)

reg delete "HKEY_CURRENT_USER\SOFTWARE\JavaSoft\Prefs\jetbrains" /f
Ancak daha sonra yine "license expired" hatası aldım. Bu sefer Windows Defender'dan "outgoing connection" için kural koydum ve IntelliJ'in dışarı bağlantısına izin vermedim. Bir müddet işe yaradı ancak yine "license expired" hatası aldım. 

Bu sefer Windows Defender'dan "incoming connection" için de kural koydum ve IntelliJ'in bağlantısına izin vermedim. 

Ayrıca gidip "C:\Users\user\AppData\Roaming\JetBrains" dizinini de sildim. Tabii bu durumda IntelliJ ayarları kayboluyor. Tekrar şunları yapmak gerekiyor.

- Help/Edit Custom VM Options ile açılan pencereye "-Duser.language=en" eklenir

- Settings/Editor/General/Auto Import penceresinde
   Add unambiguous imports on the fly
   Optimize imports on the fly
seçilir

- Settings/Editor/Code Style/Java penceresinde Imports sekmesinde
  Class count to use import with '*' 
  Names count to use static import with '*' 
99 yapılır

- Settings/Preferences/Version Control/Commit penceresinde
  Use non-modal commit interface
kapatılır

- Help/Change Memory Settings penceresinde
  Maximum Heap Size 4096 yapılır
  Ayrıca status bar'a sağ tıklayıp "Memory Indicator" gösterilir

Project Structure/Project menüsünde "Project SDK" olarak JDK 17 seçilir
File/Settings menüsünde "Gradle JVM" olarak JDK 17 seçilir


- JBoss projesinde "Startup/Connection" sekmesinde hem Run hem de Debug için tekrar şöyle yazarız.
D:\wildfly\wildfly-25.0.0.Beta1\bin\standalone.bat --server-config=standalone-full.xml
- JBoss projesinde "Deployment" sekmesinde "Deploy at the server startup" alanında artı düğmesine basılır ve Artifact olarak  "rwGuiEar.ear" seçilir
- JBoss projesinde "Server" sekmesinde "VM Options" alanına "-Duser.timezone=UTC" yazılır

Idea Dosyaları
1. .idea Dizini
Eğer IntelliJ bozulursa bu dizini silip, "File/New/Project From Existing Sources" ile proje tekrar yüklenir. maven projesi ise pom.xml seçilir.

2. .idea\runConfigurations Dosyası
.idea\runConfigurations dosyasında uygulamayı başlatma ayarları saklanır. Idea ekrandaki combobox'ta gördüğüm isim [app] foo ise dosya ismi c:\code\.idea\runConfigurations\_app_foo.xml şeklindedir.
C:\Code benim kodu checkout ettiğim yerdir.

IntelliJ Lisans Dosyası şuradadır.
C:\Users\Acelya\.IntelliJIdea2018.3\config\idea13.key
Menüler

File/New/Project From Existing Sources
maven projesi ise pom.xml seçilir.


File/Settings/Editor/Code Style/Java 
Java seçilir
1. Imports
Eğer awt ve swing import'larının otomatik olarak * ile bitmesini istemiyorsak Packages to Use Import With * kutucuğundan bu satırları kaldırmak gerekir.

2. Wrapping and Braces/Braces Placement
Süslü parantezin sınıf veya metod'da nereye geleceğini seçmek için kullanılır. Şöyle yaparız.
In method declaration : Next line
seçersek kod şöyle olur
public void Test()
{

}
In method declaration : End of line
seçersek kod şöyle olur
public void Test() {

}
File/Settings/Editor/Copyright
Bu menünün altındaki Copyright Profiles altında yeni bir telif hakkı metni oluşturulur. Bu metinde $today.year gibi değişkenler kullanılabilir.

Daha sonra Copyright menüsü altında Scope = All olarak şekilde bu yeni metin kullanılır

Örnek
Şöyle yaparız
Copyright (c) Foo Inc. and/or its affiliates, $today.year
File/Settings/Plugins
Tüm pluginler burada görülebilir.
UI Designer plugin ile Swing Formları tasarlanabilir. Bu plugin ile bound sınıf için üretilen kodu görmek için şöyle yaparız.
File → Settings → Editor > GUI Designer → Generate GUI info → tick “Java source code” (“Binary class files” is selected as default).

Edit/Find/Find...
Ctrl + F ile açık dosyada arama yapılabilir

Edit/Find/Find in Files
Ctrl + Shift + F ile tüm dosyalarda arama yapılabilir. "Find All" veya "Search Everywhere" anlamına gelir. Javadoc içinde arama olmasın istersek regex kullanarak şöyle yaparız
(?s)(?<!\/\*\*)(?<!\*\/)\bYourSearchQuery\b(?!.*\*\/)
Edit/Find/Search Structurally
Burada bir örnek var

View/Quick Documentation
Ctrl + Q ile dokümantasyon penceresi açılır.

Navigation
Navigation Menüsü yazısına taşıdım



25 Şubat 2019 Pazartesi

G1 Garbage Collector - Loglama Seçenekleri

Giriş
Java 9 ile Unified JVM Logging seçeneği olarak sadece -XLog:gc kullanılıyor. Geri kalanlar kaldırıldı. Açıklaması şöyle
Unified JVM Logging got introduced in Java SE 9 with the motivation of simplifying root-cause analysis by allowing fine-grained and easy-to-configure logging options. 
GC çıktısını etkinleştirmek performans kaybına sebep olmuyor. Bu logları incelemek için bir araç kullanmak gerekir. Açıklaması şöyle
Thus, to analyze GC logs, it’s highly recommended to use GC log analysis tools such as GCeasy, HPJmeter. These tools parse GC logs and generate great graphical visualizations of data, reports Key Performance Indicators and several other useful metrics.
Kullanım
Şöyle yaparız
Until Java 8:

Below is the system property that is supported by all versions of Java until JDK 8.

-XX:+PrintGCDetails -Xloggc:<gc-log-file-path>

Example:
-XX:+PrintGCDetails -Xloggc:/opt/tmp/myapp-gc.log

From Java 9:

Below is the system property that is supported by all versions of Java starting with 
JDK 9.

-Xlog:gc*:file=<gc-log-file-path>

Example:
-Xlog:gc*:file=/opt/tmp/myapp-gc.log

1. -Xlog:gc seçeneği
Örnek
Şöyle yaparız.
-Xlog:gc=debug:file=/tmp/gc.log
Loglardaki humongous allocation isteklerini bulmak için şöyle yaparız
# humongous allocation için
grep "source: concurrent humongous allocation" /tmp/gc.log | 
  sed 's/.*allocation request: \([0-9]*\) bytes.*/\1/' > humongous_size.txt

# Daha sonra toplamı bulmak için
awk -F',' '{sum+=$1} END{print sum;}' humoungous_size.txt

2. -Xloggc seçeneği - Kullanmayın
Bu seçenek sanırım HotSpot'a mahsustu ve Java 9 ile deprecate edildi. Dosya ismine pattern verilebilir.
Örnek
Şöyle yaparız.
"-Xloggc:/home/GCEASY/gc-%t.log"
Örnek - filecount + filesize
Şöyle yaparız
-Xlog:gc*:gc.log:time,level,tags:filecount=5,filesize=1024K
Dosyada çıktı olarak şöyle bir şey görürüz
Pause Young (Normal) (G1 Evacuation Pause) 10247M->2108M(16384M) 9.477ms
Açıklaması şöyle. Burada Java uygulaması 16GB heap ile başlatılıyor ancak 2.1GB'ye gelince GC başlıyor.
In this case, the -Xmx parameter was 16G, this is where the 16484M comes from. Garbage collection started running when 10247 MB were used, and ended up with 2108 MB after the garbage collection. Which means that you absolutely can't go below ~ 2 GB because that's what Java really needs, and shouldn't go below around double this value.
Örnek
Şöyle yaparız.
java ... -Xlog:gc*=info,heap*=debug,safepoint=info:file=/home/logs/gc.log::filecount=3,
filesize=1m FooApp
3. Java 8 ve Öncesinde Loglama Seçenekleri
Loglamayla ilgili çoğu seçenek PrintXXX şeklinde.

Bir sürü seçenek var ancak hepsini kullanmak anlamlı değil sanırım.

-XX:+PrintGCDetails  seçeneği
Prints G1 Phases
Java 8 ve öncesinde şöyle yaparız.
-XX:+PrintGCDetails -Xloggc:
Java 9 ve sonrasında şöyle yaparız
class="prettyprint"-Xlog:gc*:file=<gc-log-file-path>
Örnek 
Şöyle yaparız
-verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5
-XX:GCLogFileSize=1M
Şuna benzer bir çıktı alırız. Java 16GB heap ile başlatılıyor. GC'den önce 10.7GB kullanılıyor, GC'den sonra 2790 M'e düşüyor.
[Eden: 8176.0M(8176.0M)->0.0B(8176.0M) Survivors: 16.0M->16.0M 
Heap: 10.7G(16.0G)->2790.4M(16.0G)]
Örnek - PrintGCDateStamps
Dosyaya 2MM'lik 5 dosyaya yazdırmak için şöyle yaparız
-XX:+DisableExplicitGC 
-XX:+PrintGCDetails 
-XX:+PrintGCApplicationStoppedTime 
-XX:+PrintGCApplicationConcurrentTime 
-XX:+PrintGCDateStamps 
-Xloggc:gclog.log 
-XX:+UseGCLogFileRotation 
-XX:NumberOfGCLogFiles=5 
-XX:GCLogFileSize=2000k 
-XX:+PrintGCTimeStamps seçeneği
Prints date and uptime
Şöyle yaparız.
-XX:+PrintGCTimeStamps -XX:+PrintGCDetails
-XX:+PrintAdaptiveSizePolicy -XX:+PrintTenuringDistribution
Prints date and uptime
-XX:+PrintAdaptiveSizePolicy seçeneği
Prints ergonomic decisions
-XX:+PrintTenuringDistribution seçeneği
Print aging information of survivor regions
-XX:+UseGCLogFileRotation
Bu seçenek şöyle kullanılıyor ancak log rotasyonu pek önerilmiyor.
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/GCEASY/gc.log 
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M"