30 Kasım 2020 Pazartesi

CompletableFuture.orTimeout metodu

Giriş
Yeni bir CompletableFuture döner. Açıklaması şöyle
Exceptionally completes this CompletableFuture with TimeoutException if not otherwise completed before the given timeout.
Belirtilen süre kadar bekler. Eğer iş bitmediyse bile bile future TimeoutException ile biter.

Örnek
Şöyle yaparız
CompletableFuture<Void> f1 = ...
CompletableFuture<Void> f2 = f1.orTimeout(TIMEOUT_IN_MILLIS, TimeUnit.MILLISECONDS);

CompletableFuture.get metodu

Giriş
İmzası şöyle
V get() throws InterruptedException, ExecutionException;
Örnek
Exception'ları fırlattığı için yakalamak gerekir şöyle yaparız.
try {
  CompletableFuture.allOf(fanoutRequestList).get() 
} catch (InterruptedException | ExecutionException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}
Örnek
Tüm işlerin bitmesini beklemek için şöyle yaparız
int TIMEOUT_IN_MILLIS = 100;

@Test
public void allOfOrTimeout() throws InterruptedException, ExecutionException,
TimeoutException
{ getAllOfFuture().get(TIMEOUT_IN_MILLIS, TimeUnit.MILLISECONDS); } private CompletableFuture<Void> getAllOfFuture() { return CompletableFuture.allOf( CompletableFuture.runAsync(() -> sleep(1)), CompletableFuture.runAsync(() -> sleep(2)), CompletableFuture.runAsync(() -> sleep(3)), CompletableFuture.runAsync(() -> sleep(4)), CompletableFuture.runAsync(() -> sleep(5)), CompletableFuture.runAsync(() -> sleep(6)), CompletableFuture.runAsync(() -> sleep(7)), CompletableFuture.runAsync(() -> sleep(8)) ); } public static void sleep(int millis) { try { Thread.sleep(millis); System.out.format("Had a nap for %s milliseconds.\r\n", millis); } catch (InterruptedException e) { e.printStackTrace(); } };
Çıktı olarak şunu alırız
Had a nap for 1 milliseconds.
Had a nap for 2 milliseconds.
Had a nap for 3 milliseconds.
Had a nap for 4 milliseconds.
Had a nap for 5 milliseconds.
Had a nap for 6 milliseconds.
Had a nap for 7 milliseconds.
Had a nap for 8 milliseconds.

23 Kasım 2020 Pazartesi

Byte-code/Bytecode

Giriş
Tüm byte-code instruction listesi burada. Bytecode JVM içindeki Interpreter tarafından kullanılır. Açıklaması şöyle
The execution engine has a few sub-components. 
- Interpreter
- Profiler
- Java Native Interface
- Native Interface Library
Byte-code Kelimesi Ne Anlama Gelir
Açıklaması şöyle. Her instruction 1 byte uzunluğunda. Uzantısı ".class" olan dosyalarda byte-code instruction'lar var
Interesting fact: byte-code is called byte-code, as each instruction in byte-code is of byte length, so that it can be loaded into the CPU cache, and in fact there were also java CPUs built!!! didn’t take-off
Söz Dizimi
Söz dizimi şöyledir
opcode (1 byte)      operand1 (optional)      operand2 (optional)      ...
astore_X Instruction - store a reference into a local variable #index
Bir değişkene değer atar. Tersi ise aload_X
Örnek
Elimizde şöyle bir kod olsun
class Outer {
  private class Inner {...}

  void foo() {
    Inner a = this.new Inner();
    Inner b = new Outer.Inner();
    Inner c = new Inner();       // Recommended way to write it
  }
}
Byte-code olarak şunu elde ederiz.
0: new           #7                  // class Outer$Inner
3: dup
4: aload_0
5: invokespecial #9                  // Method Outer$Inner."<init>":(LOuter;)V
8: astore_1

9: new           #7                  // class Outer$Inner
12: dup
13: aload_0
14: invokespecial #9                  // Method Outer$Inner."<init>":(LOuter;)V
17: astore_2

18: new           #7                  // class Outer$Inner
21: dup
22: aload_0
23: invokespecial #9                  // Method Outer$Inner."<init>":(LOuter;)V
26: astore_3
getstatic Instruction
Bir sınıfın static alanına erişir
Örnek
Elimizde şöyle bir kod olsun
public static void main(String[] args) {
  System.out.println("" == ".".substring(1));
}
Çıktı olarak şunu alırız
0: getstatic     #7            // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc           #13           // String
5: ldc           #15           // String .
7: iconst_1
8: invokevirtual #17           // Method java/lang/String.substring:(I)Ljava/lang/String;
11: if_acmpne     18
14: iconst_1
15: goto          19
18: iconst_0
19: invokevirtual #23          // Method java/io/PrintStream.println:(Z)V
22: return
iX Talimatları
Integer ile çalışıldığını gösterir. Integer Instructions yazısına taşıdım



invokedynamic  Instruction
Açıklaması şöyle
This instruction was added in Java 7 with the goal of better support for dynamic languages in the JVM, such as Groovy and JRuby. 
Java da ise Lambda için kullanılıyor. Açıklaması şöyle.
Java has introduced byte code instruction invokedynamic to construct the anonymous class and then  generate byte code for lambdas. So, In case of lambdas java generates the implementation class and generate byte code at runtime.
Açıklaması şöyle. Yani CallSite bir kere yapılır
In a nutshell, an invokedynamic invocation consists of two phases: looking up a CallSite and then invoking the MethodHandle the CallSite holds. If the same invokedynamic instruction is executed another time, CallSite from the initial lookup will be invoked.
invokestatic Instruction
Bir sınıfın static metodunu çağırır
Örnek
Elimizde şöyle bir kod olsun
ByteBuffer byteBuffer = ByteBuffer.allocate(64);
byteBuffer.flip();
Java 11 byte-code çıktısı şöyledir. () karakterinden sonra metodun döndürdüğü tip görülebilir.
 0: bipush        64
 2: invokestatic  #19   // Method java/nio/ByteBuffer.allocate:(I)Ljava/nio/ByteBuffer;
 5: astore_1
 6: aload_1
 7: invokevirtual #25   // Method java/nio/ByteBuffer.flip:()Ljava/nio/ByteBuffer;
10: pop
invokevirtual Instruction
Bir sınıfın virtual metodunu çağırır

Collections.frequency metodu

İmzası şöyle. Aslında bu metodun frequency yerine count() olarak adlandırılması daha iyi olurdu.
public static int frequency(Collection<?> c, Object o)
Açıklaması şöyle.
Returns the number of elements in the specified collection equal to the specified object. More formally, returns the number of elements e in the collection such that (o == null ? e == null : o.equals(e)).
Birinci parametre içinde arama yapılacak olan liste, ikinci parametre aranılan nesnedir.  p nesnesinin equals metodunu gerçekleştiriyor olması gerekir.

Örnek
Şöyle yaparız.
int count = Collections.frequency (list, foo);
Örnek
list1'deki her elemanın list2'de kaç defa olduğunu bulmak için şöyle yaparız
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
ArrayList<Character> list1 = ...
ArrayList<Character> list2 = ...

for (Character c : list1) {
  map.put(c, Collections.frequency(list2, c));
}

17 Kasım 2020 Salı

java komutu Heap İçin -X Seçenekleri

Giriş
Heap seçenekleri megabyte veya yüzde olarak verilebilir.

1. Megabyte Seçenekleri
-Xms seçeneği - minimum heap size
Kullanılacak en az heap büyüklüğünü ayarlar. Şöyle yaparız.
"%JAVA_HOME%\bin\java" ... -Xms256m ...
Şöyle yaparız.
-Xmx2048m -Xms2048m -Xmn768m -XX:PermSize=128m -Xss256k
-Xmx seçeneği - maximum heap size
Kullanılacak en fazla heap büyüklüğünü ayarlar. Şöyle yaparız.
"%JAVA_HOME%\bin\java" ... -Xmx512m ...
Şöyle yaparız.
-Xmx1024k
-Xmx512m
-Xmx8g
2. Yüzde Seçenekleri - Genelde Container İçin Kullanılır
Açıklaması şöyle. Bu seçeneklerle container'a ayrılan belleğin şu kadar yüzdesini istiyorum ayarları daha kolay yapılır.
When we launch applications, we specify the initial memory size and maximum memory size. For the applications that run on JVM (Java Virtual Machine), initial and maximum memory size is specified through "-Xms" and "-Xmx" arguments. If Java applications are running on containers, it’s specified through "-XX:InitialRAMPercentage" and "-XX:MaxRAMPercentage" arguments
Bir başka açıklama şöyle
Java 10 introduced a new JVM flag — -XX:+UseContainerSupport (set to true by default) which allows the JVM to detect available memory and CPU if it’s running in a container environment, where these resources are limited. This flag works in conjunction with -XX:MaxRAMPercentage which lets set the maximum heap size based on the percentage of the total available memory. In the case of Kubernetes, the limit setting on the container is used as a base of this calculation. For example — if the pod has a limit of 2GB, and the MaxRAMPercentage flag is set to 75%, it’ll result in the maximum heap size of 1500MB.
Container  İle Best Practice
Benefits of Setting Initial and Maximum Memory Size to the Same Value yazısında InitialRAMPercentage ve MaxRAMPercentage değerlerini aynı yaparak uygulamanın 

1. "java.lang.OutOfMemoryError: Java heap space"
2. Operating System will terminate your application with "Out of memory: Kill process ____ (java) score ____ or sacrifice child."

gibi hatalardan korunacağı ve hatta performansının artacağı anlatılıyor. Ben denemedim

Benzer bir başka açıklama şöyle
1. Set the memory request and limit the same. That way you’ll avoid pod eviction due to insufficient node resources. More on this here.
2. Increase pod’s memory limits only in the event of Java OutOfMemory erros. In case of OOMKilled crashes, leave more memory to non-heap usage.
3. Set maximum and initial heap sizes to the same value. That way, you’ll prevent performance penalities in case of heap allocation increases and you’ll ‘fail fast’ if the heap percentage/non-heap memory/pod limits math is wrong. More on this suggestion here.

-XX:InitialRAMPercentage seçeneği 
Açıklaması şöyle. Container'ın belleğinin yüzde kaçını istediğimizi belirtir.
Suppose you are configuring -XX:InitialRAMPercentage=25 and overall physical memory (or container memory) is 1GB then your java application’s heap size will be ~250MB (i.e., 25% of 1GB).

‘-XX:InitialRAMPercentage’ will be used to derive initial heap size only if ‘-Xms’ JVM argument isn’t passed. If the ‘-Xms’ JVM argument is passed, the ‘-XX:InitialRAMPercentage’ will be ignored by the JVM.
-XX:MinRAMPercentage seçeneği
Bellek 250MB'den küçükse kullanılır. İsmi Min ile başlamasına rağmen yüzde olarak max heap size'i gösterir. Bu seçenek sanrım daha çok eğer uygulamamız IOT cihazlarda da çalışacaksa işe yarıyor. Yoksa çoğu bilgisayar - container dahi olsa - daha fazla bellek zaten sunuyor.

-XX:MaxRAMPercentage seçeneği
Bellek 250MB'den büyükse kullanılır. Yüzde olarak max heap size'i gösterir.