為什么JAVA的垃圾回收機制無法避免內存泄漏

一、本文參考:
1.《深入理解java虛擬機 JVM高級特性與最佳實踐》
2.http://coderevisited.com/memory-leaks-in-java/
二、對象已死的判定方法
要進行JVM中對象回收首先要判斷對象是否已經死亡,判斷的方法有如下幾個:
1.引用計數法
給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻 計數器為0的對象就是不可能再被使用的。
但是主流的java虛擬機里面沒有選用引用計數器算法來管理內存,其中最主要的原因是它很難解決對象之間相互循環引用的問題。
2.可達性分析算法
這個算法的基本思想就是通過一系列的稱為“GC Roots"的對象作為起始點,從這些節點開始向下搜索,搜索所走過的路徑稱為引用鏈,當一個對象到GC Roots沒有任何引用鏈相連接時,則證明此對象是不可用的。如下圖所示,對象object5、object6、object7雖然互相有關聯,但是它們到GC Roots是不可達的,所以它們將會被判定為是可回收對象。
三、導致內存泄漏的情況及代碼
java 堆內存泄漏。是由于java對象不停創建但是沒有釋放對象引用導致的。
以下是關于java代碼,此代碼是引自http://coderevisited.com/memory-leaks-in-java/
類com.code.revisited.memoryleaks.Stack提供了實現棧的一些方法,包括遍歷,入棧,出棧等操作。假設原來目的是為了現實使用(當然這里是為了解釋內存泄漏)。
package com.code.revisited.memoryleaks;import java.util.Iterator;
import java.util.NoSuchElementException;/*** @author sureshsajja* */
public class Stack<E> implements Iterable<E> {private int N;private E[] array;@SuppressWarnings("unchecked")public Stack(int capacity) {array = (E[]) new Object[capacity];}@Overridepublic Iterator<E> iterator() {return new StackIterator();}private class StackIterator implements Iterator<E> {private int i = N - 1;@Overridepublic boolean hasNext() {return i >= 0;}@Overridepublic E next() {if (!hasNext()) {throw new NoSuchElementException();}return array[i--];}@Overridepublic void remove() {throw new UnsupportedOperationException();}}public void push(E item) {if (isFull()) {throw new RuntimeException("Stack overflow");}array[N++] = item;}public E pop() {if (isEmpty())throw new RuntimeException("Stack underflow");E item = array[--N];return item;}public boolean isEmpty() {return N == 0;}public int size() {return N;}public boolean isFull() {return N == array.length;}public E peek() {if (isEmpty())throw new RuntimeException("Stack underflow");return array[N - 1];}}

類com.code.revisited.memoryleaks.StackTest用于執行棧操作。要進行入棧及出棧10000次操作,理想是入棧時分配堆內存,出棧后對象被回收。

package com.code.revisited.memoryleaks;/*** @author  sureshsajja**/
public class StackTest {/*** @param args*/public static void main(String[] args) {Stack<Integer> s = new Stack<Integer>(10000);for (int i = 0; i < 10000; i++) {s.push(i);}while (!s.isEmpty()) {s.pop();}while (true ) {// do something
              }}}
執行開始。我們使用VisualVM進行觀察。為了更明顯一些,將棧操作部分代碼注釋也執行一下。
package com.code.revisited.memoryleaks;/*** @author  sureshsajja**/
public class StackTest {/*** @param args*/public static void main(String[] args) {
//            Stack<Integer> s = new Stack<Integer>(10000);
//            for ( int i = 0; i < 10000; i++) {
//                   s.push(i);
//            }
//
//            while (!s.isEmpty()) {
//                   s.pop();
//            }while (true ) {// do something
              }}}

把棧操作的設為1號,沒有棧操作的設置為2號,分別生成Heap Dump文件,我們看一下類實例的截圖:

首先是1號截圖
首先是2號截圖
顯然預期的棧操作出棧后并沒有釋放掉Integer對象的引用(實際上看代碼也知道),所以不會被GC回收。真正的實際情況這種引用將會很隱蔽,但是根本總是由于對象仍然被引用。
四、結語
本篇僅對java堆內存泄漏進行了簡單說明,下一篇將討論其他相關的內存泄漏。有不對的地方歡迎拍磚>_<

轉載于:https://www.cnblogs.com/bobsha/p/5228335.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272248.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272248.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272248.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java里try catch的簡單用法

Java里try catch的簡單用法&#xff1a; Java里try catch的簡單用法&#xff1a; 1、trycatch 程序的流程是&#xff1a;運行到try塊中&#xff0c;如果有異常拋出&#xff0c;則轉到catch塊去處理。然后執行catch塊后面的語句 擴展部分&#xff1a; 1、trycatchfinally 程序…

【代碼筆記】iOS-點擊城市中的tableView跳轉到旅游景點的tableView,下面會有“顯示”更多。...

一&#xff0c;效果圖。 二&#xff0c;工程圖。 三&#xff0c;代碼。 RootViewController.h #import <UIKit/UIKit.h>interface RootViewController : UIViewController <UITableViewDelegate,UITableViewDataSource> {UITableView * _tableView;NSMutableArray …

Android Studio項目結構介紹

新建一個空的工程會出現以下界面&#xff1a; 從上往下依次是&#xff1a;項目名稱、包名、項目存儲的位置、項目所用的語言、項目所用的Android的系統版本。 進入之后右側可選擇界面的展示結構&#xff1a; 如果選擇Android則會出現下面的結構展示&#xff1a;MainActivity是…

對于Ping的過程,你真的了解嗎?

作者&#xff1a; 木木匠鏈接&#xff1a;https://juejin.im/post/5c15ec0f6fb9a049ec6af8b2一、概覽對于ping命令&#xff0c;想必只要是程序員都知道吧&#xff1f;當我們檢查網絡情況的時候&#xff0c;最先使用的命令肯定是ping命令吧&#xff1f;一般我們用ping查看網絡情…

Andropid自己定義組件-坐標具體解釋

在做一個view背景特效的時候被坐標的各個獲取方法搞暈了&#xff0c;幾篇抄來抄去的博客也沒弄非常清楚。 如今把整個總結一下。 事實上僅僅要把以下這張圖看明確就沒問題了。 涉及到的方法一共同擁有以下幾個&#xff1a; view獲取自身坐標&#xff1a;getLeft(),getTop(),get…

一階段結束考核題(鏈表的嵌套使用)

鏈表A&#xff0c;每個節點存放一個新的鏈表B1&#xff0c;B2,B3,B4,B5的頭結點。 場景&#xff1a;一個年級&#xff0c;相當鏈表A 該年級5個班&#xff0c;每個班5個人&#xff0c;相當于鏈表B1–B5 做一個學生成績管理系統 學生成績有語文 數學 英語 功能&#xff1a; 錄入成…

RocketMQ帶你快速入門

1. MQ介紹 ##1.1 為什么要用MQ 消息隊列是一種“先進先出”的數據結構 轉存失敗重新上傳取消 其應用場景主要包含以下3個方面 應用解耦 系統的耦合性越高&#xff0c;容錯性就越低。以電商應用為例&#xff0c;用戶創建訂單后&#xff0c;如果耦合調用庫存系統、物流系統、…

年過35歲的程序員都去哪了?一張圖道盡老程序員們的花樣出路

有人來&#xff0c;有人去。程序員何其多&#xff0c;想知道他們都去哪了嗎?對于程序員的工作出路&#xff0c;小編有以下幾點建議&#xff1a;20-27歲&#xff1a;技術積累階段假設本科22歲畢業&#xff0c;那么工作的前5年對你來說是打基礎的階段。在這5年時間里面&#xff…

em,rem

em rem 相對單位: 也可用于設置padding line-height等em相對當前容器的默認字體設置比如,所有瀏覽器默認字體都是16px,body{ font-size:62.5%}以后即1em10px; 1.2em12px 在線轉換tool: http://pxtoem.com/em(css2.0) rem(css3.0)rem相對于頁根元素的字體大小&#xff0c;即 ht…

分布式、高并發、多線程,到底有什么區別?

當提起這三個詞的時候&#xff0c;是不是很多人都認為分布式高并發多線程&#xff1f;當面試官問到高并發系統可以采用哪些手段來解決&#xff0c;或者被問到分布式系統如何解決一致性的問題&#xff0c;是不是一臉懵逼&#xff1f;確實&#xff0c;在一開始接觸的時候&#xf…

linux文件編程(open、write、read、creat、lseek函數)

文件編程內容比較多&#xff0c;如文件系統原理及訪問機制文件在內核中的管理機制&#xff0c;什么是文件信息節點iNode、文件共享、文件權限、各種用戶對其權限等等。以下主要記錄如何用代碼操作文件&#xff0c;實現文件的創建、打開、編輯等自動化執行。 文件描述符介紹、其…

記憶化搜索,FatMouse and Cheese

題目鏈接&#xff1a;http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode1107 http://acm.hdu.edu.cn/showproblem.php?pid1078 1、從gird[0][0]出發&#xff0c;每次的方向搜索一下&#xff0c;每次步數搜索一下 for(i0; i<4; i) {for(j1; j<k; j){int tx…

九種跨域方式實現原理(完整版)

前言前后端數據交互經常會碰到請求跨域&#xff0c;什么是跨域&#xff0c;以及有哪幾種跨域方式&#xff0c;這是本文要探討的內容。一、什么是跨域&#xff1f;1.什么是同源策略及其限制內容&#xff1f;同源策略是一種約定&#xff0c;它是瀏覽器最核心也最基本的安全功能&a…

文件編程練習

自己實現linux CP指令 實現cp指令的思路&#xff1a; 打開要復制的原文件讀原文件的內容到buf打開或者創建要粘貼的文件將buf里面的內容寫到目標文件關閉兩個文件 main 函數的標準原型&#xff1a; main 函數的標準原型應該是 int main(int argc, char *argv[]);argc 是命令…

java.lang.OutOfMemoryError: GC overhead limit exceeded

今天現場weblogic報java.lang.OutOfMemoryError: GC overhead limit exceeded&#xff0c;在metalink查了下&#xff0c;有明白解釋&#xff0c;要設置一個JVM參數。只是因為當前weblogic內存設置為4G&#xff0c;所以設置參數的做法事實上并非解決這個問題之道。還是要分析web…

[翻譯] Visual Studio 2019 RC版發布

今天&#xff0c;我們將分享 Visual Studio 2019 的發布候選版(RC 版) - 這是在 4 月 2 日的虛擬發布活動上正式發布之前的最后步驟之一。 您可以在 visualstudio.com/downloads 下載 RC 版。與往常一樣&#xff0c;查看RC 版的發行說明以獲取更多詳細信息。發布候選版的說明在…

fread、fwrite、fopen函數的簡單使用和open、read、write區別解析

這幾個函數的區別&#xff1a;fread、fwrite、fopen和open、read、write區別解析 標準C庫函數的簡單使用 fopen函數原型&#xff1a; #include <stdio.h> FILE *fopen(const char *pathname, const char *mode);第一個參數是&#xff1a;要打開的文件路徑 第二個參數是…

docker安裝rocketmq你學會了嗎

防火墻開通端口 9876 10911 9800 firewall-cmd --zonepublic --add-port9876/tcp --permanent firewall-cmd --zonepublic --add-port10911/tcp --permanent firewall-cmd --zonepublic --add-port9800/tcp --permanent firewall-cmd --reload 創建存儲文件夾 mkdir -p /root…