Java编程思想学习笔记_1(Java内存和垃圾回收)
1.Java中对象的存储数据的地方:
共有五个不同的地方可以存储数据.
1)寄存器.最快,因为位于处理器的内部,寄存器按需求分配,不能直接控制.
2)堆栈.位于通用RAM,通过堆栈指针可以从处理器那里获得直接支持.堆栈指针向下移动,分配新的内存,向上移动,则释放那些内存.Java系统必须知道存储在堆栈内的所有项目的确切的生命周期.
3)堆.编译器不需要知道存储的数据在堆里活多长时间.
4)常量存储.通常直接放在代码内部.
5)非RAM存储,如果数据完全存活与程序之外,那么它可以不受程序的任何控制,在程序没有运行的时候也存在,其中最基本的例子是流对象和持久化对象.
2.Java数据的存储:
根据《Java虚拟机规范》的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register)、Java栈(VM Stack)、本地方法栈(Native Method Stack)、方法区(Method Area)、堆(Heap)。
1)程序计数器,程序计数器是一块较小的区域,它的作用可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的模型里,字节码指示器就是通过改变程序计数器的值来指定下一条需要执行的指令。分支,循环等基础功能就是依赖程序计数器来完成的。在多线程中,需要通过程序计数器才可以了解到当前线程执行到哪一个位置,在下次抢到执行权后,从原来的位置开始.因此,程序计数器是线程私有的.如果虚拟机正在执行的是一个Java方法,则计数器指定的是字节码指令对应的地址,如果正在执行的是一个本地方法,则计数器指定问空undefined.
2)Java栈也被称为虚拟机栈,和程序计数器一样也是线程私有的,生命周期和线程相同,虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。每一个方法被调用的过程就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。虚拟机栈又分为局部变量表(存储方法所要用到的局部变量),操作数栈(数据结构里用来执行计算过程),指向运行时常量池的引用,方法返回地址以及附加消息.Java栈是Java方法执行的内存模型.
3)本地方法栈:Java栈是为执行Java方法服务的,本地方法栈是为执行本地方法服务的.
4)堆:在Java中用来存储对象本身(包括对象中的成员变量,数组),Java的自动垃圾回收机制主要就是回收这一部分的空间.堆是所有线程共享的,Java虚拟机只有一个堆.
5)方法区:方法区和堆一样也是被线程所共享的,在方法区中,存储了每个类的信息(包括类的名称,方法信息,字段信息),静态变量,常量以及编译器编译后的代码等。在方法区中有一个重要的部分叫做常量池,当类和接口被加载到JVM中,对于的常量池就被加载出来.在运行期间可以把新的常量放入常量池中.
3.Java的自动垃圾回收机制:终结处理和垃圾回收:
1)finalize方法详解:
finalize方法为Object的protected方法,子类可以覆盖此方法实现操作,GC在回收对象前调用此方法.不建议用finalize方法完成“非内存资源”的清理工作,但建议用于:① 清理本地对象(通过JNI创建的对象);② 作为确保某些非内存资源(如Socket、文件等)释放的一个补充:在finalize方法中显式调用其他资源释放方法.
首先,大致描述一下finalize流程:当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收.否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法.执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”.(也就是说当对象变成GC Roots不可到达的时候,对象先执行finalize方法,此时由于存在方法的调用,对象复活(但是内部标记显示已经调用过finalize方法)之后再判断的时候,如果仍然为GC Roots不可到达,且内部标记显示已经调用过finalize方法,则直接回收).可以手动的在finalize方法内部显示关闭资源或者复活对象.
另外由于finalize方法调用的不确定性(实际上垃圾回收线程的优先级是较低的),因此极有可能出现了垃圾但是未被及时回收.
2)垃圾回收器工作原理:
其他系统的垃圾回收机制:
①引用计数法
每个对象包含一个引用计数器,当有引用连接至对象的时候,引用计数+1,当引用离开作用域或被置位null的时候,引用计数-1.垃圾回收器会在含有全部对象的列表中进行遍历,如果发现某个对象计数值变为0的时候,则会立即释放该对象.但是这个方法有个缺陷,也就是对象之间存在循环调用的情况下,则会出现对象应该被回收,但是计数器却不为0的情况.如下代码演示了循环调用:
public class Test2 {
public static void main(String[] args) {
Dog d=new Dog();
Cat c=new Cat();
d.cat=c;
c.dog=d;
d=null;
c=null;
}
}
class Dog {
public Cat cat;
}
class Cat {
public Dog dog;
}
②优化的垃圾回收:
对于任何活的对象,一定能追朔到其存活在堆栈或者静态存储区之中的引用.由此,如果从堆栈和静态存储区域开始,遍历所有的引用,就能找到活的对象.对于发现的每个引用必须追踪它所引用的对象,然后是此对象包含的引用,知道根源于堆栈和静态存储区的引用所形成的网络全部被访问为止.没有被访问到的对象即是需要被垃圾回收机制处理的对象.
③Java的垃圾回收机制:
停止复制:先暂停程序的运行,然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全都是垃圾.当对象被复制到新堆的时候,它们是一个挨着一个的,所以新堆能紧凑排列.但是在Java中,大型对象仍然不会被复制.内含小型对象的那些块被复制和整理.
标记清扫:从堆栈和静态存储区出发,遍历所有的引用进而找出所有存活的对象,每当找到一个存活的对象就会设置一个标记,最后当所有标记工作都完成的时候,没有被标记的对象将会被释放.所以剩下的堆空间都是不连续的.Java虚拟机将会监视:如果所有的对象都很稳定,垃圾回收器的效率降低的话,就切换到"标记清扫"模式,同样虚拟机会跟综标记清扫的结果,如果堆空间中出现很多碎片,就会切换回停止复制方式.这就是Java虚拟机的垃圾回收机制的"自适应"技术.
4.方法接受基本数据类型时候的自动类型提升:
传入byte类型的方法:byte(优先匹配)==>short==>int==>float==>double.(byte数据不能传入char参数)
传入char类型的方法:char(优先匹配)==>int==>float==>double(跳过short,char数据不能传入short参数)
传入short类型的方法:short(优先匹配)==>int==>float==>double.
传入int类型的方法:int(优先匹配)==>float==>double.
传入float类型的方法:float(优先匹配)==>double
传入double类型的方法:只有double的参数才能匹配.
Java编程思想学习笔记_1(Java内存和垃圾回收)的更多相关文章
- Java编程思想重点笔记(Java开发必看)
Java编程思想重点笔记(Java开发必看) Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...
- [Java编程思想-学习笔记]第3章 操作符
3.1 更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...
- 【Java编程思想阅读笔记】Java数据存储位置
Java数据存储位置 P46页有感 一.前置知识 栈是由系统自动分配的,Java程序员对栈没有直接的操作权限, 堆是所有线程共享的内存区域,栈 是每个线程独享的. 堆是由程序员自己申请的,在使用new ...
- [Java编程思想-学习笔记]第1章 对象导论
1.1 抽象过程 Java是一门面向对象的语言,它的一个优点在于只针对待解问题抽象,而不用为具体的计算机结构而烦心,这使得Java有完美的移植性,也即Java的口号"Write Once, ...
- Java编程思想 学习笔记5
五.初始化与清理 1.用构造器确保初始化 在Java中,通过提供构造器,类的设计者可确保每个对象都会得到初始化.创建对象时,如果其类具有构造器,Java就会在用户有能力操作对象之前自动调用相应的构造 ...
- [Java编程思想-学习笔记]第2章 一切都是对象
2.1 创建新的数据类型:类 通过第一章掌握了面向对象的理论后,我们知道每个对象必定属于一个类型,那么Java如何创建新的数据类型?如下程序所示: class Circle { // 属性 // 方 ...
- Java编程思想 学习笔记4
四.控制执行流程 1.true和false 所有条件语句都利用条件表达式的真或假来决定执行路径.注意Java不允许我们将一个数字作为布尔值使用. 2.if-else 3.迭代 while.do-whi ...
- Java编程思想学习笔记——注解
前言 在Android开发的过程中,我们为了减少重复代码的编写,会使用类似ButterKnife,AndroidAnnotations 这类依赖注解库.代码示例如下: //不使用 Button btn ...
- Java编程思想学习笔记——初始化与清理
初始化 构造器保证初始化 构造器采用与类相同的名称. 默认构造器(default constructor):不接受任何参数的构造器,也叫无参构造器. 构造器也能带有形式参数,就能在初始化对象时提供实际 ...
随机推荐
- 【转】Tomcat中部署java web应用程序
http://www.blogjava.net/jiafang83/archive/2009/06/02/279644.html 转载:今天给大家介绍怎样在Tomcat5.5.9中部署Java Web ...
- c# web 缓存管理
using System; using System.Collections; using System.Text.RegularExpressions; using System.Web; usin ...
- 20150625_Andriod_02_ListView2_多条目显示_选中
android listview 参考地址: http://www.cnblogs.com/zhengbeibei/archive/2013/05/14/3078805.html http://xy ...
- The trouble of Xiaoqian
The trouble of Xiaoqian Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- drivers/mfd/Mfd-core.c
mfd: multifunction device drivers---多功能设备驱动开发:A product or device that has multiple functions. An ex ...
- mvc api
===============================首页===================================================== 扫码 快递公司接口uri: ...
- 用户名 不在 sudoers文件中,此事将被报告。(转)
话说昨天新建了一个帐号linc,今天在执行sudo时回显一个很吓人的信息: [sudo] password for linc: linc 不在 sudoers 文件中.此事将被报告. 这是要去哪儿报告 ...
- SqlSever基础 rtrim与ltrim嵌套使用 除去字符串左右两边的空格
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- Cheatsheet: 2013 11.01 ~ 11.11
Other Back To Basics: Hashtables – Part2 How To Make A Game Part 1:Picking a Framework Modern Garbag ...
- 【转载】.NET面试题系列[0] - 写在前面
原文:.NET面试题系列[0] - 写在前面 索引: .NET框架基础知识[1] - .NET框架基础知识(1) http://www.cnblogs.com/haoyifei/p/5643689.h ...