垃圾回收机制和数据结构栈链表

1、垃圾回收机制:

(1)没有引用变量指向的对象,就是垃圾。

举例:

Test t = new Test();

t=null;

那么之前创建的对象就是垃圾。

(2)对象没有被使用是另外一种垃圾。

new Test();

new Test().toString();

区别在于第一个对象很明显没有指向,是垃圾。但是第二个不是,因为他被使用了。

2、回收时机。

通常情况下,要在满了的时候回收。

其次在调用

System.gc();//通常情况下会立刻回收。等效于Runtime.getRuntime.gc();

3、finalize() 方法,是任何对象都有的一个方法。(Object )

任何对象在被回收之前都会调用的一个方法。finalize().

这个方法的函数体是空的。

方法描述:

Runs the garbage collector.Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

The call System.gc() is effectively equivalent to the call:

Runtime.getRuntime().gc()

运行垃圾回收器:

调用gc方法 建议java虚拟机增强性能通过回收未利用的对象,让内存中已经被占用的快速能够再次被使用。当控制器返回这个方法调用后,java虚拟机能够更好地重新声明控件,从所有废弃的对象那里。

调用System.gc()方法等效于 Runtime.getRuntime.gc();

记得找到 class 来执行

Code:
package GarbageCollectin;
public class GarbageCollection {

    public static void main(String[] args) {

        GarbageCollection gc  = new GarbageCollection();
         new GarbageCollection();
         new GarbageCollection().toString();
         gc = null;
         Runtime.getRuntime().gc();//等效于 System.gc();

         System.runFinalization();
         //这样直接运行并没有结果。
    }
}

数据回收前对内存的数量被占用的数量是:3932k

回收后是: 728K

后面的 251392K是虚拟机占用的总的内存大小。

在后面是 所用时长。

【我只在这种路径下尝试成功。再建立一层目录结构就无法实现】

通过包名。找到对应路径:

然后找到对应的 文件路径:

F:\zhongruan\GarbageClear\bin

在cmd命令里面:使用 java -verbosegc Garbage 命令,就可以得到如上图的结果。

刀下留人:

可以在Finalize()方法里面实现 即将被杀死的对象的起死回生。

示例:

而且 每次执行的结果不都一样。

在命令行里面恒只有一个

不恒了。。。笑哭,通常都是只有一个 执行了么 。

并不知道是为什么  10次以上都是这个结果。

执行的太快,还没救活,就死了,所以需要系统沉睡一下Thread.sleep(1000)。

什么是数据结构!!!

都忘记了。

定义的存储数据的规则。

数组: 连续存储数据的一种结构。

容器:list set map iterator

变量:严格来讲不属于数据结构,只是存储数据的空间。只是一个类型

数据库:是复杂的存储数据的结构。是一个系统

数组 链表 队列 栈

栈:像弹夹一样,对于数据是先进后出。

链表结构: 单项链表 和双向链表

节点: 指向下一个阶段标示(引用变量)

数组和链表结构对比:数组遍历效率高 增加删除效率低

链表遍历麻烦, 但是增加删除 效率高。

老师的那个 链表 实在是 不敢恭维,有问题 绝对有问题:下面给出一个 我写的感觉没问题的链表:当然 栈也一并给出:

栈部分源代码:

package MyStack;
public class MyStack {
    private Object[] ob=new Object[2];
    private int index=0;
    public void push(Object object){
        if(index<ob.length){
            ob[index++]=object;
        }else {
            Object[] newob = new Object[ob.length*2];
            newob[index++]=object;
            for(int i=0;i<ob.length;i++){
                newob[i]=ob[i];
            }
            ob=newob;
        }
    }
    public Object pop(){
        if(index==0){return null;}
        else{
            return ob[--index];
        }
    }
    public Object peek(){
        if(index==0)return null;
        return ob[index-1];
    }
    public int getSize(){
        return index;
    }
}

测试部分不再给出。

链表:

说实话面试的时候考察链表真的很帅,既考察了面向对象又考察了算法。这就是当初我被刷下来的原因吧。所以 这次上完课还是好好琢磨了一下 链表,记得有时间实现链表的reverse。

有面向对象的思想,因为 它的基底是一个 节点对象:

package MyList;
public class Node {
    private Object object;
    private Node next;
    public Node() {
        super();
    }
    public Object getObject() {
        return object;
    }
    public void setObject(Object object) {
        this.object = object;
    }
    public Node getNext() {
        return next;
    }
    public void setNext(Node next) {
        this.next = next;
    }
    public Node(Object object) {
        super();
        this.object = object;
    }
    @Override
    public String toString() {
        return "Node [object=" + object + "]";
    }
}

然后是链表的方法:这也是人家真正想要考察的内容。

package MyList;
/**
 * 在这链表中,第一个添加的元素作为头结点,最后添加的作为尾节点
 * @author Administrator
 *
 */
public class MyList {
    private int size=0;
    private Node temp;
    private Node head;
    private Node tail;
    public void add(Object obj){
        size++;
        temp= new Node(obj);
        if(tail==null){
            tail = temp;
            head = temp;
        }else{
            tail.setNext(temp);
            tail=temp;
        }
    }
    /**
     * 返回链表长度
     * @return
     */
    public int getSize(){
        return size;
    }
    /**
     * 得到头结点
     * @return
     */
    public Node getHead(){
        if(head!=null)
            return head;
        return null;
    }
    /**
     * 得到尾节点
     * @return
     */
    public Node getTail(){
        if(tail!=null)
            return tail;
        return null;
    }
    /**
     * 得到节点或者空
     * @param obj
     * @return 返回这个值对应的节点
     */
    public Node find(Object obj){
        //如果链表里什么都没有那就返回null
        if(head==null)
            return null;
        //执行到这里,说明链表不为空
        temp = head;
        if(temp.getObject().equals(4)){
            return temp;
        }else{
            return find(obj,temp);
        }
    }
    /**
     * 内部使用的用于找到如果head不为所要被查找的元素的情况下所使用的递归函数
     * 循环调用自身
     * @param obj  要被查找的项目
     * @param temp 临时变量,用以一个一个的往后面查找节点
     * @return 返回要被查找的节点
     */
    private Node find(Object obj, Node temp) {
        temp=temp.getNext();
        //先判断一次是否相等
        if(temp.getObject().equals(obj)){
            return temp;
        }else{//不等的话,判断是否进入temp 已经移到了 head 返回null,否则继续执行本方法
            if(temp==tail){
                return null;
            }else{
                return find(obj,temp);
            }
        }
    }
    //遍历所有节点
    public void lookoutAllNode(){
        //如果头结点为空,
        if(head==null){
            System.out.println("链表中尚未添加元素");
        }else{
            //否则一定里面有元素
            System.out.println(head);
            lookoutNext(head);
        }
    }
    //被封装的用于循环调用的查找下一个节点的方法
    private void lookoutNext(Node head) {
        temp=head.getNext();
        System.out.println(temp);
        if(temp==tail){
            //遍历结束
            System.out.println("遍历结束");
        }else{
            lookoutNext(temp);
        }
    }
    /**
     * 根据输入的内容删除对应元素
     * @param object
     * @return
     */
    public Node delete(Object object){
        //没有元素
        if(head==null){
            return null;
        }else{//有元素
            //如果头 就是的话
            if(head.getObject().equals(object)){
                //看看有几个元素,有没有必要顺延?
                size--;
                temp=head;
                if(head==tail){//首尾相同
                    head=null;
                    tail=null;
                    return temp;
                }else{//头不是尾
                        temp=head;
                        head=head.getNext();
                        temp.setNext(null);
                        return temp;
                }
            }else{//头不是的话
                return delete(object,head);
            }
        }
    }
    private Node delete(Object object, Node n) {
        //当前节点的下一个不可到达
        if(n==tail){
            return null;
        }else{//头不是尾的话
            if(n.getNext().getNext()!=null){//当前节点的下一个的下一个可到达
                if(n.getNext().getObject().equals(object)){
                    size--;
                    temp=n.getNext();
                    n.setNext(n.getNext().getNext());
                    temp.setNext(null);
                    return temp;
                }else{
                    return delete(object,n.getNext());
                }
            }else{//当前节点的仅下一个可到达
                if(tail.getObject().equals(object)){//就是尾巴
                    size--;
                    temp=tail;
                    tail=n;
                    n.setNext(null);
                    return temp;
                }else{//不是尾巴
                    return null;
                }
            }
        }
    }
}
时间: 2024-10-08 13:42:44

垃圾回收机制和数据结构栈链表的相关文章

4.5-全栈Java笔记:垃圾回收机制

垃圾回收机制(Garbage  Collection) Java引入了垃圾回收机制,令C++程序员最头疼的内存管理问题迎刃而解.JAVA程序员可以将更多的精力放到业务逻辑上而不是内存管理工作上,大大的提高了开发效率. 垃圾回收原理和算法 1)内存管理 Java的内存管理很大程度指的就是对象的管理,其中包括对象空间的分配和释放. 对象空间的分配:使用new关键字创建对象即可 对象空间的释放:将对象赋值null即可.垃圾回收器将负责回收所有"不可达"对象的内存空间. 2)垃圾回收过程 任何

垃圾回收机制GC知识再总结兼谈如何用好GC(其他信息: 内存不足)

来源 一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般有如下几种: 1.手动管理:C,C++ 2.计数管理:COM 3.自动管理:.NET,Java,PHP,GO- 但是,手动管理和计数管理的复杂性很容易产生以下典型问题: 1.程序员忘记去释放内存 2.应用程序访问已经释放的内存 产生的后果很严重,常见的如内存泄露.数据内容乱码,而且大部分时候,

垃圾回收机制GC知识再总结兼谈如何用好GC

一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般有如下几种: 1.手动管理:C,C++ 2.计数管理:COM 3.自动管理:.NET,Java,PHP,GO… 但是,手动管理和计数管理的复杂性很容易产生以下典型问题: 1.程序员忘记去释放内存 2.应用程序访问已经释放的内存 产生的后果很严重,常见的如内存泄露.数据内容乱码,而且大部分时候,程序的

.Net 垃圾回收机制原理(一)

英文原文:Jeffrey Richter 编译:赵玉开 链接:http://www.cnblogs.com/yukaizhao/archive/2011/11/23/dot_net_GC_1.html 有了Microsoft.Net clr中的垃圾回收机制程序员不需要再关注什么时候释放内存,释放内存这件事儿完全由GC做了,对程序员来说是透明的.尽管如此,作为一个.Net程序员很有必要理解垃圾回收是如何工作的.这篇文章我们就来看下.Net是如何分配和管理托管内存的,之后再一步一步描述垃圾回收器工作

.NET垃圾回收机制(二)

一.GC的必要性 1.应用程序对资源操作,通常简单分为以下几个步骤:为对应的资源分配内存 → 初始化内存 → 使用资源 → 清理资源 → 释放内存. 2.应用程序对资源(内存使用)管理的方式,常见的一般有如下几种: [1] 手动管理:C,C++ [2] 计数管理:COM [3] 自动管理:.NET,Java,PHP,GO- 3.但是,手动管理和计数管理的复杂性很容易产生以下典型问题: [1] 程序员忘记去释放内存 [2] 应用程序访问已经释放的内存 产生的后果很严重,常见的如内存泄露.数据内容乱

.NET垃圾回收机制 转

首先明确一点:就是值类型变量(bool byte char decimal double enum float int long sbyte short struct uint ulong ushort)是存储在栈上的(是先进后出的数据结构),它是由OS管理的,即出了作用域,操作系统自动释放相关内存,不需要CLR参与:而CLR管理的引用类型(class, interface, delegate, object, string)的对象,这些对象是存储在堆中的(是先进先出的数据结构),所以说.net

【转】.NET垃圾回收机制

文章来源:http://www.cnblogs.com/anorthwolf/archive/2009/12/07/1618744.html 在.NET Framework中,内存中的资源(即所有二进制信息的集合)分为"托管资源"和"非托管资源".托管资源必须接受.NET Framework的CLR(通用语言运行时)的管理(诸如内存类型安全性检查),而非托管资源则不必接受.NET Framework的CLR管理. (了解更多区别请参阅.NET Framework或C

js的垃圾回收机制

Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理:是当变量进入环境时,将这个变量标记为“进入环境”.当变量离开环境时,则将其标记为“离开环境”.标记“离开环境”的就回收内存. 工作流程: 1.    垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记. 2.    去掉环境中的变量以及被环境中的变量引用的变量的标记. 3.    再被加上标记的会被视为准备删除的变量. 4.    垃圾回收器完成内存清除工作,销毁那

Java性能优化之JVM GC(垃圾回收机制)

Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行.当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成.GC优化很多时候就是减少stop-the-world 的发生. JVM GC回收哪个区域内的垃圾? 需要注意的是,JV