Java etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Java etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

5 Mart 2014 Çarşamba

JVM Havuzları

Not : JVM ile ilgili tanımlamaları burada gördüğüm sözlükten okumak mümkün.

Komut Satırından Java Kaynak Dosyaları Derlemek
src altındaki bazı kaynak dosyaları derlemek için

set sourcefiles = src\main.java src\another.java
javac -d bin -cp lib\myjar.jar;lib\myotherjar.jar -sourcepath src -verbose %sourcefiles%


Java ClassPath
JVM ile alakası yok ancak not almak istedim. Bir jar dosyasını çalıştırmak için iki yol var. İlkinde CLASSPATH ortam değişkeni ile yüklenecek jar dosyalarının bulunduğu dizin belirtilir. Örnek:

set CLASSPATH=D:\Mylib\
Daha sonra java MyApp şeklinde çalıştırılır. 

İkincisinde ise jar dosyaları -cp ile belirtilir. Örnek:


Linux'ta ; yerine : karakteri kullanılır.Örnek:

Daha sonra yine aynı şekilde java MyApp şeklinde çalıştırılır.
 
Young Generation Nedir?

Bir çok nesnenin çok kısa süreliğine kullanılıp tekrar yok olacağı farz ediliyor. Bu kısa ömürlü nesneler Young Generation denilen havuzda toplanırlar. Young Generation iki kısımdan oluşuyor. Eden ve Survivor.

Eden:
Burada anlatıldığına göre Eden ismi nesneler burada doğdukları için verilmiş. Eğer nesne hayatta kalırlarsa "Young Generation" içindeki diğer alanlara  gönderilirler.

 Survivor:
Survivor da kendi içinde to ve from isimli iki havuzdan oluşuyor.

 
Permenant Generation Nedir ?
Bu konuda bir sürü karmaşık yazı var. Benim anladığım işin özeti şöyle. Eğer bir yazılımda çok fazla yüklenecek class ya da string varsa bazen bu hata alınabiliyor. Tek yapılması gereken -XX:MaxPermSize=128M gibi bir parametre ile daha yüksek bir değer vermek.

-Xmx işe yaramaz ! Boşuna uğraşmayın...

Burada da classloader'ın nasıl çalıştığı anlatılıyor.

Aşağıda buradan aldığım bir şekil var ve durumu çok güzel anlatıyor.
Manifest Dosyası
Permenant Generation içine yüklenen class bilgilerinin bazısı jar dosyası içindeki manifest dosyasından gelir. META-INF/MANIFEST.MF dizinindeki dosyada jar yüklenirken çalıştırılan satırlar bulunur.
Main-Class:

jar -cp classpath -jar my.jar komutu ile çalıştırılan bir jar'ın giriş sınıfını bu satırda belirtiriz.

Class-Path:
Jar dosyasının ihtiyacı olan diğer jar dosyalarını belirtir. Örnek:

Tüm Heap

Tüm Heap'in büyüklüğünü almak için aşağıdaki kod parçası çalıştırılabilir.

Runtime rt = Runtime.getRuntime();
long maxMb = rt.maxMemory()/(1024*1024);
Old Generation Nedir?

Uzun ömürlü nesneler Old Generation denilen havuzda toplanırlar.


Young + Old Generation Büyüklüğünü Ayarlamak

-Xms500m : Bu alanın başlangıç büyüklüğünü ayarlar.
why jvm consume less memory than -Xms speicified? sorusunda da gösterildiği gibi top komutuyla bakılınca VIRT sütunu altındaki değer -Xms ile atanan değerden daha büyük olmalı.

-Xmx1024m : Bu alanın azami büyüklüğünü ayarlar
Bu ayarlar ile java.lang.OutOfMemoryError: Java heap space diye başlayan exceptionlardan genellikle kurtulmak mümkün oluyor.

32 bit JVM'ler için bu alanın alacağı en büyük değer -Xmx1628m civarında. Yani 1.6 gigabyte.

Young + Old Generation Büyüklüğünü Yüzde Olarak Ayarlamak

JVM hafıza alanlarını işletim sisteminden bir kere alınca, normal şartlar altında kullanmasa bile işletim sistemine iade etmek zorunda değildir. Ancak

-XX:MinHeapFreeRatio (default is 40)   ve
-XX:MaxHeapFreeRatio (default is 70)

seçenekleri ise kullanılmayan alanın geri verilmesi sağlanabilir. Örneğin ilk açılışta çok bellek lazımdır ve üst sınır yüksek tutulmalıdır. Ancak daha sonra bu kadar bellek gerekmez ve "boş alan" miktarı artar. Bu durumda JVM kullanmadığı alanları işletim sistemine geri verirse, diğer uygulamalar daha rahat çalışırlar.

Garbage Collector
GC için tek thread çalışır.

Garbage Collection ve Strong Reference

Strong Reference bir nesneye Root Set tarafından direkt erişilebilmesi demek. Bu tür nesneler GC tarafından yok edilmezler. Aşağıdaki şekilde Root Set tarafından Strong Reference ile erişilebilen nesneleri görmek mümkün.

Bir diğer şekilde ise aynı durumu bu sefer GC tarafından yok edilecek nesneler ile birlikte görmek mümkün. Özellikle birbirine strong reference ile bağlı olan 3 nesnenin oluşturduğu adacığın Root Set'e bağlı olmadıkları için kırmızı ile işaretlendiğine dikkat etmek lazım.


Thread'ler bir şekilde çalıştıkları müddetçe, strong reference'a sahipler. Thread yarattıktan sonra, herhangi bir referans tutulmasa bile, thread nesnesi çalıştığı müddetçe garbage collection'a uğramaz.

Garbage Collector Tarafından Çağırılan Metodlar
Bir nesne yok edilirken Java'da finalize(), C#'ta ise Dispose() metodu çağırılıyor. Bu metodların içinde unmanaged resource'lar varsa onları serbest bırakmak mümkün.

Java finalize metodu
Garbage collection varsa finalize metodundan bahsetmeden geçmek olmaz. finalize metodunu kullanmaktan kaçınmak lazım ancak illaki kullanılması gerekiyorsa Do you call super.finalize() within a subclass? sorusunda da cevaplandığı gibi her sınıf kendi üst sınıfının da finalize metodunu çağırmalı.
C# Dispose Metodu
Bu metodu gerçekleştirmek için  IDisposable arayüzünden türemek gerekir.

C#'ta Dispose İşleminin Hemen Çağırılması
using ifadesi içine bir veya daha çok sınıf verilerek kod bloğundan çıkınca kaynakların hemen bırakılması sağlanabilir. Örnek:


Java'da şu anda using benzeri bir kullanım yok ancak Java 7'de buradaki gibi olacak.

Java Closeable Arayüzü
Java'da C#'taki gibi using kullanımı yok ancak bazı sınıflar için özel bir arayüz geliştirilmiş.
Özellikle stream sınıfları Closeable arayüzünden türüyorlar. Bu arayüz ile finalize metodunun çalıştırılmasını beklemeden stream kapatılabiliyor ve kaynaklar serbest kalabiliyor. Closeable arayüzü close() metodunda IOException attığı için daha çok stream'ler için düşünülmüş. Örneğin ResultSet  veya socket sınıfları close() metodları olmasına rağmen bu arayüzü kullanmıyorlar.
 
JVM Environment Variables
Windows altında heap boyunu ayarlamak için eğer Oracle JVM kullanılıyorsa _JAVA_OPTIONS değişkeni atanabilir.
Headless Mode
Bu modda çalıştırılan java uygulamasına display ve keyboard verilmez. Örnek:

jps
JVM ile çalışan programları görmek için jps kullanılabilir. jps JDK dizini altında bulunur. Örneği benim bilgisayarımda C:\Program Files (x86)\Java\jdk1.7.0_02\bin dizini altında bulunuyor.

3 Mart 2014 Pazartesi

Reflection

Reflection ve Encapsulation
Reflection encapsulation'ın bir noktaya kadar bozulabilmesini sebep olabilir. Ancak birim testi gibi yerlerde bu tür kabiliyetler çok faydalı oluyor.
 
Java Reflection Notları

Java reflection ile ilgili olarak Hibernate,JPA ve Default Constructor başlıklı yazıya göz atabilirsiniz.

Java'da reflection için iki önemli paket var. Bunlar java.lang.reflect ve java.beans paketleri.

java.lang.reflect sınıfları
Java'daki reflection işlerini yapan en önemli sınıflar Class, Method.

java.beans paketindeki sınıflar
Introspector, PropertyDescriptor, BeanInfo

Class Sınıfı ile kullanılabilen metodlar
Oracle örneği burada.

Bu sınıftaki metodların isimleri yerine getirdikleri işlevi yansıtıyor. getDeclared...() şeklindeki metodlar, public olan veya olmayan bilgiye erişebilir. get...() ile başlayan metodlar ismi veya imzası verilen public bilgiye erişebilir. get...s() şeklindeki çoğul metodlar ise public olan veya olmayan bilgiye bir array şeklinde erişebilir.

isAssignableFrom

Bu metod Parametre olarak verilen nesnenin/sınıfın diğer sınıfın altsınıfı veya kendisi olup olmadığını döner. Type erasure'dan dolayı reflection içinde bazen kullanmak gerekir. Örnek:


forName
Bu metod "fully qualied" yani tam ismiyle verilen sınıfı yaratabilmemizi sağlar. Eğer yaratılmak istenen sınıfın ismi eksik verilirse, ClassNotFoundException atar.

java.lang.Class.getConstructor - verilen imzaya sahip public constructor'a erişir

Bu metod ile sınıfın belli bir imzaya sahip veya default constructor metodunu bulup o sınıfı yaratmak mümkün.

MyPanel extends Panel{
    public MyPanel (String id){
        super (id);
    }
}

Class<? extends Panel> c = MyPanel.class;
//Panel constructor'ını bul
Constructor<? extends Panel> ctor = c.getConstructor(String.class);
//Paneli yarat
Panel panel = ctor.newInstance(panelId);
getConstructors
Örnek:
Constructor<?>[] array = c.getConstructors();
for (Constructor ctr : mbrs) {
 out.format("  %s%n", ctr.toGenericString());
}

java.lang.Class.getDeclaredConstructor - verilen imzaya sahip public olan veya olmayan constructor'a erişir

Bu metod ile bir sınıfın public olan veya olmayan tüm constructorlarına erişilebilir. Örneği buradan aldım.


getDeclaredField - Verilen isme sahip public olan veya olmayan Field'a erişir
Konuyu Reflection ile Fieldlara erişmek başlıklı yazıya taşıdım.

getField - Verilen isme sahip public Field'a erişir
Konuyu Reflection ile Fieldlara erişmek başlıklı yazıya taşıdım.

getFields - Tüm field'lara erişir
Konuyu Reflection ile Fieldlara erişmek başlıklı yazıya taşıdım.

getDeclaredMethod - Verilen isme sahip public olan veya olmayan  Method'a erişir

Bu metod ile sınıfa ait public veya non-public tüm Method'lara erişilebilir.


getMethod -  Verilen isme sahip public Method'a erişir
Bu metod ile kalıtımla gelen veya sıfın için tanımlanmış olan tüm public method'lara erişilebilir. Örnek:

Burada da açıklandığı gibi private erişimi ile tanımlanmış bazı iç sınıfların metodlarına erişmek istenirse IllegalAccessException alınabilir. Bu gibi durumlarda yapılması gereken setAccessible (true) yöntemi ile reflection ile elde edilen Method sınıfını erişilebilir kılmaktır.

getPackage - Sınıfın paketine erişilir
Örnek:
Class<?> c = Class.forName("fully qualified name");
Package p = c.getPackage();
out.format("Package:%n  %s%n%n",(p != null ? p.getName() : "-- No Package --"));
Yan not olarak Java'da "Package Visible" denilen bir kavram var. Eğer bir sınıfın başına modifier konulmazsa, sadece paket içinden kullanılabilir.

newInstance
Konuyu Reflection ile Nesne Yaratmak başlıklı yazıya taşıdım.

Method sınıfı 
getName
Metodun ismini döner

getDeclaringClass
Metodun hangi sınıfta tanımlandığını belirtir.

getGenericParameterTypes
Metodun generic parametresi vars dizi şeklinde döner. Örnek:

invoke - parametre almayan bir metodu çağırma örneği
 
Örnek: Örnekte metodun parametre almadığını belirtmek için variable argument olarak hiç bir şey geçilmiyor.

setAccessable - parametre almayan ve public olmayan bir metodu çağırma örneği


Örneği buradan aldım.Örnekte metodun parametre almadığını belirtmek için boş bir array kullanılıyor. setAccessable ile private metodların güvenliğinin tehlikeye atıl atılmadığı ise burada konuşulmuş.
//no paramater
Class noparams[] = {};

//load the class at runtime
Class targetClass = Class.forName("com.reflection.Test");
Object obj = targetClass.newInstance();
      
Method method = targetClass.getDeclaredMethod("testMethod",noparams);

//Set accessible provide a way to access private methods too
method.setAccessible(true);

//call the  method
method.invoke(obj, null);

Introspector sınıfı ile kullanılabilen metodlar
 
java.beans.Introspector.getBeanInfo
Bu metod ile verilen bean ve üst sınıfları ile reflection kullanmak çok daha kolay. Örnek:

AnnotatedElement arayüzü ile kullanılabilen metodlar
java.lang.reflectAnnotatedElement.isAnnotationPresent metodu bir Field ve Method ile anotasyon varmı diye kontrol etmeye yarar. Örnek:
public class SamplePojo {
    @Column(name="User_Id")
    int id;
}
Class outputClass = SamplePojo.class;
Field[] fields = outputClass.getDeclaredFields();
for (Field field : fields) {
    if (field.isAnnotationPresent(Column.class)) {
        //Do something...
    }
}
Apache Commons Reflection Notları
Apache Commons bir çok kullanması kolay sını sunuyor.
BeanComparator Sınıfı
Bu sınıfı kullanarak, reflection ile nesneleri sıralamak mümkün. Örnek:
new BeanComparator("name");//artan sıralama
new BeanCompartor("name", Collections.reverseOrder());//azalan sıralama

BeanUtils Sınıfı
Bu sınıf ve PropertyUtils hemen hemen aynı şeyleri yapıyor gibi görünüyor, ancak aralarında önemli bir fark var. BeanUtils verilen parametreyi, setter metodunda kullanılan tipe çevirmeye çalışıyor. Örneğin double tipindeki bir alana, string verilse bile işe çalışır. PropertyUtils bu çevrimi yapmıyor.

getProperty() ve setProperty() metodları ile verilen bir bean'in alan ismi kullanılarak getter/setter metodu çağırılabilir. Örneği burada bulabilirsiniz.

MethodUtils Sınıfı
invokeMethod
Reflection ile bir nesnenin metodunu çağırmak mümkün. 
Örnek:
Parametre almayan bir metodu çağırmak için.

PropertyUtils
Verilen property alanına getter/setter metodları ile erişir.
copyProperties
Bu metod ile bir bean'in property'leri diğerine kopyalanır.

getProperty
Bu metod dot notation şeklinde kullanıma izin veriyor sanıyorum.

setProperty
PropertyUtils.setProperty(beanObject, property, value.trim());
şeklinde kullanılabilir.

Apache Commons Byte Code Engineering Library (BCEL)
ClassParser sınıfı
Örnek:

ClassParser parser=new ClassParser(getClass().getResourceAsStream("/my/package/MyClass.class"), "MyClass.class");
JavaClass javaClass=parser.parse();
javaClass.getMethods(); // Get whatever info you need

C# Reflection Notları
Activator Sınıfı
Bu sınıf ile verilen tipte nesne yaratmak mümkün.
CreateInstance metodu
Konuyu Reflection ile Nesne Yaratmak başlıklı yazıya taşıdım.

Assembly
Bu sınıf ta Activator gibi nesne yaratabiliyor.

CreateInstance metodu
Konuyu Reflection ile Nesne Yaratmak başlıklı yazıya taşıdım.

Dynamic Method
Dinamik olarak bir metod yaratabilme yeteneğini sağlar. Örnek:

FieldInfo
Konuyu Reflection ile Fieldlara erişmek başlıklı yazıya taşıdım.

MethodInfo Sınıfı
invoke
Parametre alan bir metodu çağırma örneği:
 
Type Sınıfı
Type sınıfı Java'daki Object.getClass() ile elde edilen sınıfa denk geliyor.
 
typeof()
Type sınıfı typeof() veya Type.GetType() metodları ile elde ediliyor.

GetGenericArguments
Aşağıdaki kodda generic parametrenin adı öğrenilebiliyor.
List myObj = new List<Data>();
myObj.GetType().GetGenericArguments()[0].Name;
 

 
GetProperty - İsim ile bir PropertyInfo sınıfı bulmaya yarar
Bu metod ile ismi bilinen bir property bulunabilir.

GetProperties
Bu metod ile tüm property'ler sizi şeklinde alınabilir. Örnek:
IsAssignableFrom
Bir sınıfın başka sınıftan türeyip türemediğini belirtir. Örnek'te baseType sınıfından türeyen sınıfların isimleri bulunuyor.
var names = assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t)).Select(t => t.Name);
 
IsGenericType
Sorgulanan sınıfın generic olup olmadığını belirtir.

PropertyInfo Sınıfı
Bu sınıf Java'daki PropertyDescriptor sınıfına benziyor. 

GetValue
Örnek:


 
Win32 Reflection Notları
LoadLibrary ve GetProcAddress ile imzası bilinen bir metodu bulmak ve çağırmak mümkün.
Örnek:
HINSTANCE hDLL = LoadLibrary("C:\\cusp.dll");
if(hDLL == NULL)
{
cout
<< "Failed to load DLL" <<endl;
}

typedef void(*fnPtr)(int *, double);

fnPtr pfn
;

pfn
=(fnPtr)GetProcAddress(hDLL,"cuspDsolver");

if(pfn)
{
pfn
(rowOffset,0.9);
}

FreeLibrary(hDLL);
Linux Reflection Notları
dlsym metodu ile imzası bilinen bir metodu bulmak ve çağırmak mümkün.
so yüklemek, metod bulmak ve çağırmak
Örnek:
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;

handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}

cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}

printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
}
Zaten yüklü metodları bulmak ve çağırmak
Örnek:
#include <dlfcn.h>
#include <stdio.h>

void main_greeting(void)
{
printf
("%s\n", "hello world");
}

void lib_func(void)
{
void (*greeting)(void) = dlsym(RTLD_MAIN_ONLY, "main_greeting");

greeting
? greeting() : printf("%s\n", dlerror());
}

int main(void)
{
lib_func
();

return 0;
}
Bir başka örnekte ise dlsym()'in çalışması için -ldl ile derlenmesi gerektiği hatırlatılmış. Örnek:
#define _GNU_SOURCE     /* for RTLD_NEXT */
#include <dlfcn.h>
/* ... */
void (*exit_addr)(int) = dlsym(RTLD_NEXT, "exit");



Bir shared object dosyası (so) bir de fazla yazılım tarafından yükleniyorsa, ve so içinde const olmayan değişkenler varsa, her yazılım bu değişkenin ayrı bir kopyasını kullanır

C++ Reflection Notları
C++ ile tabiki reflection gelmiyor. Ancak işimizi kolaylaştıracak ve reflection'ı andıran bir güzel kullanımı not etmek istedim. Her sınıfa eşi olmayan bir numara vererek bu sınıfı bir hasmap'te saklayabiliriz. Örnek:
Önce bir arayüz atanımlanır. Daha sonra bu arayüzü gerçekleştiren ve statik bir alan ekleyen bir macro kendi sınıfımızın header dosyasına eklenir. Yine sınıfımızın cpp dosyasına sayaca değer atacak bir başka macro eklenir.

class MyInterface{
virtual int getID() = 0;
};

class MyClass : public MyInterface{
COMPONENT(); //Arayüzü gerçekleştiren macro

SET_ID(MyClass); //cpp dosyasındaki sayaçtan yeni değeri alan macro

#define  COMPONENT()\
static int ID;\//Statik değişken tanımla
int getID(){return ID};//Arayüzü gerçekleştir

#define SET_ID(Component)\
int Component::ID = GetNextID();//GetNextID sayaçtan gelen yeni sayı

SCRIPTING
Java
Java'da scripting JSR-223 ile yapılıyor.
ScriptEngineManager
Bu sınıf classpath içindeki tüm script engine sınıflarını yönetir.

getEngineByName
İsmi verilen ScriptEngine sınıfını döndürür. Örnek:
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine e = sem.getEngineByName("ECMAScript");

getEngineFactories
ScriptEngineFactory sınıflarının listesini döner.

ScriptEngine sınıfı
Bu sınıfı verilen script'i çalıştırır.
eval
C#

Reflection ile tam alakası olmasa da bu yazıya eklemek mantıklı geldi. Buradaki sorudan yola çıkarak aşağıdaki örnekte kod çalıştırma gösteriliyor.