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; } } } } }