广东平台网站建设制作,wordpress postviews,酒店网站建设设计,科技感背景素材一、本文参考#xff1a;1.《深入理解java虚拟机 JVM高级特性与最佳实践》2.http://coderevisited.com/memory-leaks-in-java/二、对象已死的判定方法要进行JVM中对象回收首先要判断对象是否已经死亡#xff0c;判断的方法有如下几个#xff1a;1.引用计数法给对象中添加一个…一、本文参考 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 StackE implements IterableE {private int N;private E[] array;SuppressWarnings(unchecked)public Stack(int capacity) {array (E[]) new Object[capacity];}Overridepublic IteratorE iterator() {return new StackIterator();}private class StackIterator implements IteratorE {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) {StackInteger s new StackInteger(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) {
// StackInteger s new StackInteger(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