JVM'de Belleği Anlamak
Bildiğiniz üzere JVM Java programlarını kendi bünyesinde çalıştırmaktadır. Herhangi bir sanal makine gibi, kendi bellek organizasyon sistemine sahiptir.
Dahili bellek düzeni, Java uygulamanızın nasıl çalıştığını gösterir. Bu şekilde, uygulamaların ve algoritmaların işleyişindeki darboğazlar belirlenebilir. Nasıl çalıştığını görelim.
Önemli! Orijinal Java modeli yeterince iyi değildi, bu nedenle Java 1.5'te revize edildi. Bu sürüm bugüne kadar kullanılmaktadır (Java 14+).
İplik Yığını
JVM tarafından dahili olarak kullanılan Java bellek modeli, belleği iş parçacığı yığınlarına ve yığınlara ayırır. Mantıksal olarak bloklara bölünmüş Java bellek modeline bakalım:
JVM'de çalışan tüm iş parçacıklarının kendi yığınları vardır . Yığın ise, iş parçacığının hangi yöntemleri çağırdığı hakkında bilgi tutar. Buna "çağrı yığını" diyeceğim. Çağrı yığını, iş parçacığı kodunu yürüttüğü anda kaldığı yerden devam eder.
İş parçacığının yığını, iş parçacığının yığınında yöntemleri yürütmek için gereken tüm yerel değişkenleri içerir. Bir iş parçacığı yalnızca kendi yığınına erişebilir. Yerel değişkenler diğer iş parçacıkları tarafından görülemez, yalnızca onları oluşturan iş parçacığı tarafından görülebilir. İki iş parçacığının aynı kodu yürüttüğü bir durumda, her ikisi de kendi yerel değişkenlerini oluşturur. Böylece, her iş parçacığının her yerel değişkenin kendi versiyonu vardır.
İlkel türlerin ( boolean , byte , short , char , int , long , float , double ) tüm yerel değişkenleri tamamen iş parçacığı yığınında saklanır ve diğer iş parçacıkları tarafından görülmez. Bir iş parçacığı, ilkel bir değişkenin bir kopyasını başka bir iş parçacığına iletebilir, ancak ilkel bir yerel değişkeni paylaşamaz.
Yığın
Yığın, nesneyi hangi iş parçacığının oluşturduğuna bakılmaksızın uygulamanızda oluşturulan tüm nesneleri içerir. Bu, ilkel türdeki sarmalayıcıları içerir (örneğin, Byte , Integer , Long vb.). Nesnenin yaratılıp yerel bir değişkene atanmış olması veya başka bir nesnenin üye değişkeni olarak oluşturulmuş olması fark etmez, öbek üzerinde depolanır.
Aşağıda, çağrı yığınını ve yerel değişkenleri (yığınlarda depolanırlar) ve ayrıca nesneleri (yığın üzerinde depolanırlar) gösteren bir diyagram bulunmaktadır:
Yerel değişkenin ilkel bir türde olması durumunda, iş parçacığının yığınında depolanır.
Yerel bir değişken ayrıca bir nesneye referans olabilir. Bu durumda, referans (yerel değişken) iş parçacığı yığınında depolanır, ancak nesnenin kendisi yığında depolanır.
Bir nesne yöntemleri içerir, bu yöntemler yerel değişkenleri içerir. Bu yerel değişkenler ayrıca, yöntemin sahibi olan nesne yığında depolansa bile iş parçacığı yığınında depolanır.
Bir nesnenin üye değişkenleri, nesnenin kendisi ile birlikte yığında saklanır. Bu, hem üye değişkeni ilkel bir türde olduğunda hem de bir nesne başvurusu olduğunda geçerlidir.
Statik sınıf değişkenleri de sınıf tanımıyla birlikte yığında depolanır.
nesnelerle etkileşim
Öbek üzerindeki nesnelere, nesneye referansı olan tüm iş parçacıkları tarafından erişilebilir. Bir iş parçacığının bir nesneye erişimi varsa, nesnenin değişkenlerine de erişebilir. İki iş parçacığı aynı nesne üzerinde aynı anda bir yöntem çağırırsa, her ikisi de nesnenin üye değişkenlerine erişebilir, ancak her iş parçacığı yerel değişkenlerin kendi kopyasına sahip olacaktır.
İki iş parçacığının bir dizi yerel değişkeni vardır.Yerel Değişken 2öbek üzerinde paylaşılan bir nesneye işaret eder (nesne 3). Her iş parçacığının, kendi referansıyla yerel değişkenin kendi kopyası vardır. Referansları yerel değişkenlerdir ve bu nedenle iş parçacığı yığınlarında depolanır. Ancak, iki farklı başvuru öbek üzerinde aynı nesneye işaret eder.
Lütfen genelnesne 3bağlantıları varnesne 2Venesne 4üye değişkenler olarak (oklarla gösterilmiştir). Bu bağlantılar aracılığıyla, iki iş parçacığı erişebilirnesne 2VeNesne4.
Diyagram ayrıca yerel bir değişkeni de gösterir (yerel değişken 1methodTwo'dan ) . Her kopyası, iki farklı nesneye işaret eden farklı referanslar içerir (nesne 1Venesne 5) ve aynı değil. Teorik olarak, her iki iş parçacığı da her ikisine de erişebilirnesne 1, öyleysenesne 5bu nesnelerin her ikisine de referansları varsa. Ancak yukarıdaki şemada, her iş parçacığının iki nesneden yalnızca birine bir referansı vardır.
Nesnelerle etkileşime bir örnek
Çalışmayı kodda nasıl gösterebileceğimizi görelim:
public class MySomeRunnable implements Runnable() {
public void run() {
one();
}
public void one() {
int localOne = 1;
Shared localTwo = Shared.instance;
//... do something with local variables
two();
}
public void two() {
Integer localOne = 2;
//... do something with local variables
}
}
public class Shared {
// store an instance of our object in a variable
public static final Shared instance = new Shared();
// member variables pointing to two objects on the heap
public Integer object2 = new Integer(22);
public Integer object4 = new Integer(44);
}
run() yöntemi one() yöntemini çağırır ve one() sırayla two() yöntemini çağırır .
one() yöntemi, ilkel bir yerel değişken bildirir (yerelBir) türünde int ve yerel bir değişken (yerel İki), bir nesneye referanstır.
one() yöntemini yürüten her iş parçacığı kendi kopyasını oluşturacaktıryerelBirVeyerel İkiyığınınızda. DeğişkenleryerelBirher iş parçacığının yığını üzerinde olmak üzere birbirinden tamamen ayrılacaktır. Bir iş parçacığı, başka bir iş parçacığının kendi kopyasında yaptığı değişiklikleri göremezyerelBir.
one() yöntemini yürüten her iş parçacığı kendi kopyasını da oluştururyerel İki. Ancak iki farklı kopyayerel İkiöbek üzerinde aynı nesneyi işaret ederek sona erer. Gerçek şu kiyerel İkistatik değişken tarafından başvurulan nesneye işaret edermisal. Bir statik değişkenin yalnızca bir kopyası vardır ve bu kopya yığında depolanır.
Yani her iki kopyayerel İkisonunda aynı Paylaşılan örneğe işaret ediyor . Paylaşılan örnek ayrıca yığında depolanır. Uyumlunesne 3yukarıdaki şemada.
Shared sınıfının ayrıca iki üye değişken içerdiğini unutmayın . Üye değişkenlerin kendileri, nesne ile birlikte öbek üzerinde depolanır. İki üye değişken, diğer iki nesneye işaret ediyortamsayı. Bu tamsayı nesneleri şuna karşılık gelir:nesne 2Venesne 4diyagram üzerinde.
Ayrıca, two() yönteminin adlı yerel bir değişken oluşturduğuna dikkat edin.yerelBir. Bu yerel değişken, Tamsayı türündeki bir nesneye başvurudur . Yöntem bağlantıyı ayarlaryerelBiryeni bir Tamsayı örneğini işaret etmek için . Bağlantı, kopyasında saklanacakyerelBirher iş parçacığı için. Öbekte iki Tamsayı örneği depolanacak ve yöntem her yürütüldüğünde yeni bir Tamsayı nesnesi oluşturduğundan, bu yöntemi yürüten iki iş parçacığı ayrı Tamsayı örnekleri oluşturacaktır . Eşleşiyorlarnesne 1Venesne 5yukarıdaki şemada.
İlkel bir tür olan Tamsayı türündeki Shared sınıfındaki iki üye değişkene de dikkat edin . Bu değişkenler üye değişkenler olduğundan, nesneyle birlikte yığında depolanırlar. İş parçacığı yığınında yalnızca yerel değişkenler depolanır.
GO TO FULL VERSION