❶ 返回內存泄漏警告問題,怎麼解決
為什麼會產生內存泄漏?
當一個對象已經不需要再使用本該被回收時,另外一個正在使用的對象持有它的引用從而導致它不能被回收,這導致本該被回收的對象不能被回收而停留在堆內存中,這就產生了內存泄漏。
內存泄漏對程序的影響?
內存泄漏是造成應用程序OOM的主要原因之一。我們知道Android系統為每個應用程序分配的內存是有限的,而當一個應用中產生的內存泄漏比較多時,這就難免會導致應用所需要的內存超過系統分配的內存限額,這就造成了內存溢出從而導致應用Crash。
如何檢查和分析內存泄漏?
因為內存泄漏是在堆內存中,所以對我們來說並不是可見的。通常我們可以藉助MAT、LeakCanary等工具來檢測應用程序是否存在內存泄漏。
1、MAT是一款強大的內存分析工具,功能繁多而復雜。
2、LeakCanary則是由Square開源的一款輕量級的第三方內存泄漏檢測工具,當檢測到程序中產生內存泄漏時,它將以最直觀的方式告訴我們哪裡產生了內存泄漏和導致誰泄漏了而不能被回收。
常見的內存泄漏及解決方法
1、單例造成的內存泄漏
由於單例的靜態特性使得其生命周期和應用的生命周期一樣長,如果一個對象已經不再需要使用了,而單例對象還持有該對象的引用,就會使得該對象不能被正常回收,從而導致了內存泄漏。
示例:防止單例導致內存泄漏的實例
❷ 電腦內存泄漏怎麼解決
所謂的內存泄漏可以理解為內存單元逐漸被無用的數據佔用,在c c++里可以通過內存單元沒有釋放引起,java里可以通過未對作廢數據內存單元的引用置null引起分配了內存而沒有釋放,逐漸耗盡內存資源,導致系統崩潰。
內存泄露是指程序中間動態分配了內存,但是在程序結束時沒有釋放這部分內存,從而造成那一部分內存不可用的情況,重起計算機可以解決,但是也有可能再次發生內存泄露,內存泄露和硬體沒有關系,它是由軟體設計缺陷引起的。
內存泄漏可以分為4類:
1.常發性內存泄漏。發生內存泄漏的代碼會被多次執行到,每次被執行的時候都會導致一塊內存泄漏。
2. 偶發性內存泄漏。發生內存泄漏的代碼只有在某些特定環境或操作過程下才會發生。常發性和偶發性是相對的。對於特定的環境,偶發性的也許就變成了常發性的。所以測試環境和測試方法對檢測內存泄漏至關重要。
3. 一次性內存泄漏。發生內存泄漏的代碼只會被執行一次,或者由於演算法上的缺陷,導致總會有一塊僅且一塊內存發生泄漏。比如,在類的構造函數中分配內存,在析構函數中卻沒有釋放該內存,所以內存泄漏只會發生一次。
4. 隱式內存泄漏。程序在運行過程中不停的分配內存,但是直到結束的時候才釋放內存。嚴格的說這里並沒有發生內存泄漏,因為最終程序釋放了所有申請的內存。但是對於一個伺服器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內存也可能導致最終耗盡系統的所有內存。所以,我們稱這類內存泄漏為隱式內存泄漏。
❸ 關於內存泄漏的解決方案
把內存條拔下來用稀硫酸洗一下應該能解決
開個玩笑。有些程序可以檢測並釋放程序中分配但未使用的內存(不特指360加速球),應該能減少內存佔用,不過治本之策仍然是少開占內存的程序
❹ 什麼是內存泄露內存泄露該如何解決
1、內存泄漏指由於疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。
2、一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程序從堆中分配的,大小任意的,
使用完後必須顯式釋放的內存。應用程序一般使用malloc,calloc,realloc,new等函數從堆
中分配到一塊內存,使用完後,程序必須負責相應的調用free或delete釋放該內存塊,否則
這塊內存就不能被再次使用,就是這塊內存泄漏了。
3、內存泄露多數屬於程序本身設計問題,有以下幾種解決方法:
1)從程序內部重新編譯。養成良好的編碼習慣,盡量在涉及內存的程序段,檢測出內存泄露。
2)結束程序,內存自然就會被操作系統回收。
3)重新啟動電腦後,立刻恢復。
❺ 如何解決內存泄漏問題
第一,良好的編碼習慣,盡量在涉及內存的程序段,檢測出內存泄露。當程式穩定之後,在來檢測內存泄露時,無疑增加了排除的困難和復雜度。
使用了內存分配的函數,要記得要使用其想用的函數釋放掉,一旦使用完畢。
Heap memory:
malloc\realloc ------ free
new \new[] ---------- delete \delete[]
GlobalAlloc------------GlobalFree
要特別注意數組對象的內存泄漏
MyPointEX *pointArray =new MyPointEX [100];
其刪除形式為:
delete []pointArray
Resource Leak :對於系統資源使用之前要仔細看起使用方法,防止錯誤使用或者忘記釋放掉系統資源。
我們看MSDN上一個創建字體的例子:
RECT rect;
HBRUSH hBrush;
FONT hFont;
hdc = BeginPaint(hWnd, &ps);
hFont = reateFont(48,0,0,0,FW_DONTCARE,FALSE,TRUE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, VARIABLE_PITCH,TEXT(「Impact」));
SelectObject(hdc, hFont);
SetRect(&rect, 100,100,700,200);
SetTextColor(hdc, RGB(255,0,0));
DrawText(hdc, TEXT(「Drawing Text with Impact」), -1,&rect, DT_NOCLIP); DeleteObject(hFont);
EndPaint(hWnd, &ps);
❻ 怎麼解決內存泄漏js
意外的全局變數
js中如果不用var聲明變數,該變數將被視為window對象(全局對象)的屬性,也就是全局變數.
function foo(arg) {
bar = "this is a hidden global variable";
}123
// 上面的函數等價於
function foo(arg) {
window.bar = "this is an explicit global variable";
}123
所以,你調用完了函數以後,變數仍然存在,導致泄漏.
如果不注意this的話,還可能會這么漏:
function foo() {
this.variable = "potential accidental global";
}123
// 沒有對象調用foo, 也沒有給它綁定this, 所以this是window
foo();
你可以通過加上』use strict』啟用嚴格模式來避免這類問題, 嚴格模式會組織你創建意外的全局變數.
被遺忘的定時器或者回調
var someResource = getData();
setInterval(function() {
var node = document.getElementById('Node'); if(node) {
node.innerHTML = JSON.stringify(someResource));
}
}, 1000);1234567
這樣的代碼很常見, 如果id為Node的元素從DOM中移除, 該定時器仍會存在, 同時, 因為回調函數中包含對someResource的引用, 定時器外面的someResource也不會被釋放.
沒有清理的DOM元素引用
var elements = { button: document.getElementById('button'), image: document.getElementById('image'), text: document.getElementById('text')
};function doStuff() {
image.src = 'http://some.url/image';
button.click(); console.log(text.innerHTML);
}function removeButton() { document.body.removeChild(document.getElementById('button')); // 雖然我們用removeChild移除了button, 但是還在elements對象里保存著#button的引用
// 換言之, DOM元素還在內存裡面.
}123456789101112131415161718
閉包
先看這樣一段代碼:
var theThing = null;var replaceThing = function () {
var someMessage = '123'
theThing = {
someMethod: function () {
console.log(someMessage);
}
};
};123456789
調用replaceThing之後, 調用theThing.someMethod, 會輸出123, 基本的閉包, 我想到這里應該不難理解.
解釋一下的話, theThing包含一個someMethod方法, 該方法引用了函數中的someMessage變數, 所以函數中的someMessage變數不會被回收, 調用someMethod可以拿到它正確的console.log出來.
接下來我這么改一下:
var theThing = null;var replaceThing = function () {
var originalThing = theThing; var someMessage = '123'
theThing = {
longStr: new Array(1000000).join('*'), // 大概佔用1MB內存
someMethod: function () {
console.log(someMessage);
}
};
};1234567891011
我們先做一個假設, 如果函數中所有的私有變數, 不管someMethod用不用, 都被放進閉包的話, 那麼會發生什麼呢.
第一次調用replaceThing, 閉包中包含originalThing = null和someMessage = 『123』, 我們設函數結束時, theThing的值為theThing_1.
第二次調用replaceThing, 如果我們的假設成立, originalThing = theThing_1和someMessage = 『123』.我們設第二次調用函數結束時, theThing的值為theThing_2.注意, 此時的originalThing保存著theThing_1, theThing_1包含著和theThing_2截然不同的someMethod, theThing_1的someMethod中包含一個someMessage, 同樣如果我們的假設成立, 第一次的originalThing = null應該也在.
所以, 如果我們的假設成立, 第二次調用以後, 內存中有theThing_1和theThing_2, 因為他們都是靠longStr把佔用內存撐起來, 所以第二次調用以後, 內存消耗比第一次多1MB.
如果你親自試了(使用Chrome的Profiles查看每次調用後的內存快照), 會發現我們的假設是不成立的, 瀏覽器很聰明, 它只會把someMethod用到的變數保存下來, 用不到的就不保存了, 這為我們節省了內存.
但如果我們這么寫:
var theThing = null;var replaceThing = function () {
var originalThing = theThing; var unused = function () {
if (originalThing)
console.log("hi");
}; var someMessage = '123'
theThing = {
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log(someMessage);
}
};
};123456789101112131415
unused 這個函數我們沒有用到, 但是它用了 originalThing 變數, 接下來, 如果你一次次調用 replaceThing , 你會看到內存1MB 1MB的漲.
也就是說, 雖然我們沒有使用 unused , 但是因為它使用了 originalThing , 使得它也被放進閉包了, 內存漏了.
強烈建議讀者親自試試在這幾種情況下產生的內存變化.
這種情況產生的原因, 通俗講, 是因為無論 someMethod 還是 unused , 他們其中所需要用到的在 replaceThing 中定義的變數是保存在一起的, 所以就漏了.
❼ 遇到內存泄露提示應該怎麼解決
主要代碼在OnTimer函數里,列出如下
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void CShuaKeDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if(1 == nIDEvent) {
if(1 == flag) {
::PostMessage(m_hWebPage, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(m_drag.m_TargetPoint.x, m_drag.m_TargetPoint.y));
::PostMessage(m_hWebPage, WM_LBUTTONUP, MK_LBUTTON, MAKELONG(m_drag.m_TargetPoint.x, m_drag.m_TargetPoint.y));
flag = 2;
}
else if(2 == flag) {
CWnd* m_Dlg = NULL;
m_Dlg = FindWindow(NULL, "來自網頁的消息");
if(m_Dlg) {
m_Dlg->PostMessage(WM_KEYDOWN, VK_RETURN, NULL);
m_Dlg->PostMessage(WM_KEYUP, VK_RETURN, NULL);
flag = 1;
}
}
}
CDialog::OnTimer(nIDEvent);
}
然後在運行的時候,不知什麼時候就出現個內存泄露~提示在afxwin2.inl的41行。對應位置代碼如下
C/C++ code
?
1
{ ASSERT(::IsWindow(m_hWnd)); return ::PostMessage(m_hWnd, message, wParam, lParam); }
❽ 怎樣解決Java中內存泄露
一旦知道確實發生了內存泄漏,就需要更專業的工具來查明為什麼會發生泄漏。JVM自己是不會告訴您的。這些專業工具從JVM獲得內存系統信息的方法基本上有兩種:JVMTI和位元組碼技術(byte code instrumentation)。Java虛擬機工具介面(Java Virtual Machine Tools Interface,JVMTI)及其前身Java虛擬機監視程序介面(Java Virtual Machine Profiling Interface,JVMPI)是外部工具與JVM通信並從JVM收集信息的標准化介面。位元組碼技術是指使用探測器處理位元組碼以獲得工具所需的信息的技術。
Optimizeit是Borland公司的產品,主要用於協助對軟體系統進行代碼優化和故障診斷,其中的Optimizeit Profiler主要用於內存泄漏的分析。Profiler的堆視圖就是用來觀察系統運行使用的內存大小和各個類的實例分配的個數的。
首先,Profiler會進行趨勢分析,找出是哪個類的對象在泄漏。系統運行長時間後可以得到四個內存快照。對這四個內存快照進行綜合分析,如果每一次快照的內存使用都比上一次有增長,可以認定系統存在內存泄漏,找出在四個快照中實例個數都保持增長的類,這些類可以初步被認定為存在泄漏。通過數據收集和初步分析,可以得出初步結論:系統是否存在內存泄漏和哪些對象存在泄漏(被泄漏)。
接下來,看看有哪些其他的類與泄漏的類的對象相關聯。前面已經談到Java中的內存泄漏就是無用的對象保持,簡單地說就是因為編碼的錯誤導致了一條本來不應該存在的引用鏈的存在(從而導致了被引用的對象無法釋放),因此內存泄漏分析的任務就是找出這條多餘的引用鏈,並找到其形成的原因。查看對象分配到哪裡是很有用的。同時只知道它們如何與其他對象相關聯(即哪些對象引用了它們)是不夠的,關於它們在何處創建的信息也很有用。
最後,進一步研究單個對象,看看它們是如何互相關聯的。藉助於Profiler工具,應用程序中的代碼可以在分配時進行動態添加,以創建堆棧跟蹤。也有可以對系統中所有對象分配進行動態的堆棧跟蹤。這些堆棧跟蹤可以在工具中進行累積和分析。對每個被泄漏的實例對象,必然存在一條從某個牽引對象出發到達該對象的引用鏈。處於堆棧空間的牽引對象在被從棧中彈出後就失去其牽引的能力,變為非牽引對象。因此,在長時間的運行後,被泄露的對象基本上都是被作為類的靜態變數的牽引對象牽引。
總而言之, Java雖然有自動回收管理內存的功能,但內存泄漏也是不容忽視,它往往是破壞系統穩定性的重要因素。
❾ 內存泄露怎麼解決
普通在調試環境中,如果用Debug調試運行程序的話,在程序運行結束後,調試系統會自動將泄露的內存回收,問題不大。非Debug運行則無法回收泄露的內存,只能重啟系統解決。
❿ 內存泄漏怎麼解決
CTypedPtrArray<CObArray, CText*>m_TextArray;你的內存泄漏
程序終止時析構
for(int i=0;i<m_TextArray.GetSize();i++)delete m_TextArray[i];
m_TextArray.RemoveAll();