本文目錄一覽:
JAVA裡面存在內存泄露問題嗎
存在的,內存泄漏是指,不再使用的內存沒有及時的回收,嚴重的內存泄漏會因過多的內存佔用導致程序奔潰,GC線程判斷對象是否可以回收的依據是該對象是否有引用指向,因此,當確定該對象不再使用時,應該及時將其引用設置為null;
java中存在內存泄漏問題嗎
會。java導致內存泄露的原因很明確:長生命周期的對象持有短生命周期對象的引用就很可能發生內存泄露,儘管短生命周期對象已經不再需要
什麼原因可導致java內存泄漏?
Java內存泄露
一般來說內存泄漏有兩種情況。一種情況如在C/C++語言中的,在堆中的分配的內存,在沒有將其釋放掉的時候,就將所有能訪問這塊內存的方式都刪掉(如指針重新賦值);另一種情況則是在內存對象明明已經不需要的時候,還仍然保留着這塊內存和它的訪問方式(引用)。第一種情況,在Java中已經由於垃圾回收機制的引入,得到了很好的解決。所以,Java中的內存泄漏,主要指的是第二種情況。
可能光說概念太抽象了,大家可以看一下這樣的例子:
1 Vector v=new Vector(10);
2 for (int i=1;i100; i++){
3 Object o=new Object();
4 v.add(o);
5 o=null;
6 }
在這個例子中,代碼棧中存在Vector對象的引用v和Object對象的引用o。在For循環中,我們不斷的生成新的對象,然後將其添加到Vector對象中,之後將o引用置空。問題是當o引用被置空後,如果發生GC,我們創建的Object對象是否能夠被GC回收呢?答案是否定的。因為,GC在跟蹤代碼棧中的引用時,會發現v引用,而繼續往下跟蹤,就會發現v引用指向的內存空間中又存在指向Object對象的引用。也就是說儘管o引用已經被置空,但是Object對象仍然存在其他的引用,是可以被訪問到的,所以GC無法將其釋放掉。如果在此循環之後,Object對象對程序已經沒有任何作用,那麼我們就認為此Java程序發生了內存泄漏。
儘管對於C/C++中的內存泄露情況來說,Java內存泄露導致的破壞性小,除了少數情況會出現程序崩潰的情況外,大多數情況下程序仍然能正常運行。但是,在移動設備對於內存和CPU都有較嚴格的限制的情況下,Java的內存溢出會導致程序效率低下、佔用大量不需要的內存等問題。這將導致整個機器性能變差,嚴重的也會引起拋出OutOfMemoryError,導致程序崩潰。
一般情況下內存泄漏的避免
在不涉及複雜數據結構的一般情況下,Java的內存泄露表現為一個內存對象的生命周期超出了程序需要它的時間長度。我們有時也將其稱為“對象遊離”。
例如:
1 public class FileSearch{
2
3 private byte[] content;
4 private File mFile;
5
6 public FileSearch(File file){
7 mFile = file;
8 }
9
10 public boolean hasString(String str){
11 int size = getFileSize(mFile);
12 content = new byte[size];
13 loadFile(mFile, content);
14
15 String s = new String(content);
16 return s.contains(str);
17 }
18 }
在這段代碼中,FileSearch類中有一個函數hasString,用來判斷文檔中是否含有指定的字符串。流程是先將mFile加載到內存中,然後進行判斷。但是,這裡的問題是,將content聲明為了實例變量,而不是本地變量。於是,在此函數返回之後,內存中仍然存在整個文件的數據。而很明顯,這些數據我們後續是不再需要的,這就造成了內存的無故浪費。
要避免這種情況下的內存泄露,要求我們以C/C++的內存管理思維來管理自己分配的內存。第一,是在聲明對象引用之前,明確內存對象的有效作用域。在一個函數內有效的內存對象,應該聲明為local變量,與類實例生命周期相同的要聲明為實例變量……以此類推。第二,在內存對象不再需要時,記得手動將其引用置空。
複雜數據結構中的內存泄露問題
在實際的項目中,我們經常用到一些較為複雜的數據結構用於緩存程序運行過程中需要的數據信息。有時,由於數據結構過於複雜,或者我們存在一些特殊的需求(例如,在內存允許的情況下,儘可能多的緩存信息來提高程序的運行速度等情況),我們很難對數據結構中數據的生命周期作出明確的界定。這個時候,我們可以使用Java中一種特殊的機制來達到防止內存泄露的目的。
之前我們介紹過,Java的GC機制是建立在跟蹤內存的引用機制上的。而在此之前,我們所使用的引用都只是定義一個“Object o;”這樣形式的。事實上,這只是Java引用機制中的一種默認情況,除此之外,還有其他的一些引用方式。通過使用這些特殊的引用機制,配合GC機制,就可以達到一些我們需要的效果。
Java 語言寫的程序會不會內存泄漏
當然會,當該被釋放的對象沒有釋放,一直被某個或某些實例所持有卻不再被使用導致 GC 不能回收。就可能導致內存泄漏.
java在什麼情況下會出現內存泄露
內存泄露就是指一個不再被程序使用的對象或變量一直被佔據在內存中。java中的內存泄露的情況:
1.長生命周期的對象持有短生命周期對象的引用就很可能發生內存泄露,例如,緩存系統,我們加載了一個對象放在緩存中(例如放在一個全局map對象中),然後一直不再使用它,這個對象一直被緩存引用,但卻不再被使用。
2.集合類,而如果集合類是全局性的變量(比如類中的靜態屬性,全局性的map等即有靜態引用或final一直指向它),那麼沒有相應的刪除機制,很可能導致集合所佔用的內存只增不減,因此提供這樣的刪除機制或者定期清除策略非常必要。
3.單例模式。不正確使用單例模式是引起內存泄露的一個常見問題,單例對象在被初始化後將在JVM的整個生命周期中存在(以靜態變量的方式),如果單例對象持有外部對象的引用,那麼這個外部對象將不能被jvm正常回收,導致內存泄露
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/227859.html