第五章 初始化与清理
今天是清明长假的第一天,看了自己的博客,人很少,呵呵,我想这和我第一次发布应用的情况也是一样的,但是我相信这一点随着自己的深入研究,自然会多起来,就我个人而言,第五章是这本书有趣的开始,有很多知识是我之前没有去碰过的,当然这些基础知识也相当重要,这让我想起了自己当时去面试,连很多基础的问题都不懂得回答,哎,所以说基础还是非常重要的.
好吧,看看今天有什么内容
.不安全编程
在许多c程序员忘记初始化变量,或者在使用程序库后,不记得清理,导致了元素占用一直没有释放,所以资源耗尽,导致程序出错,在java这边,很好的解决了这两个问题,而这一章书也是围绕着这两个点说的 初始化 清理
.构造器
构造器的名字,若命名为普通方法名,容易与正常方法冲突,又因为构造器是编译器的责任,故构造器的名字与类名同名(c++也是这样),若编译器探测到程序内无显式构造器,则会提供一个默认构造器,也就是无参构造器,对于java而言,创建与初始化是捆绑在一起的, 注:构造器无返回值
.方法重载
为什么需要方法重载,这样说一下程序,我记得我上软件工程选修课的时候,老师说过一句挺经典的话,程序是真实世界的反应,它不能真正帮你解决什么问题....我现在是有点感悟了,重载的意思在人类语言来说就是一个词表示多重含义,
比如看电视,看电脑,看书,重载了看这个方法,传入的参数类型不同而已,
区别重载方法的技巧,其实很简单,看他的方法签名就好了,方法签名就是方法名加参数列表(类型顺序不同,方法也不同,但是不建议这么做),thats all,有些人可能会问,返回值类型不同也可以区分啊,但是有时候你在调用有返回值的方法,但是你不需要它的返回值,例如 hello(); 你能判别这个方法是有返回值还是木有吗,呵呵,所以说以返回值判断是不行的,记得private void shit()和public void shit()这两个不是方法重载,会出错的...
.this关键字
这个this,作者是这样引出来的,a.peel(1),b.peel(2),对于这两个对象调用peel方法,怎么知道是哪个对象调用呢,其实编译器做了一些幕后工作,就是将该对象的引用作为第一参数传入到方法 故a.peel(a,1)
那么this是什么,我个人的平时用法就是this就是当前对象的引用,书上是这么说的,在方法内部获得对当前对象的引用,若在同一个类的方法内调用其他方法,可以不写this,this会自动应用
this应用的地方,1.引用成员变量,例如x.name;可以写成this.name
2.在构造器中调用构造器constructor(){this(“hello”);} 且必须写在第一句 注:在构造器外不能调用构造 器,this不能用于两个构造器
3.返回对象的值,可以用 return this;
注:静态方法内不能用this
.static
statci 方法内部不能调用非静态方法(对象引用的例外)与变量,非静态方法可以调用static方法与变量
.清理 垃圾回收器
这是一块比较大得内容,在下面的引用网络那里会详细研究
.初始化
我觉得是这一章最难懂的,
1.成员初始化
局部变量必须初始化,类变量可以不用(系统自动初始化)
2.构造器初始化
先初始化变量,在初始化构造器,java编译器为了安全起见
3.静态数据的初始化
static不能用于局部变量,这是真的,的确会出错
static数据最先初始化
.显示的静态初始化:后于变量,前于方法
1.static{}首次访问类的静态成员或方法,都会触动到static静态块的调用
2.首次生成类的对象时会调用,要注意是首次
.数组初始化
例如int【】 a
数组是一个对象
length属性,这是数组的固有成员,java数组内置边界检查,性能降低,但是安全性大大提高
Java中数组下标从0开始
在创建数组时,允许使用变量作为数组长度
Autoboxing:对于一个包装类类型的数组,可以直接对每个元素赋值上相应的基本数据类型
.可变参数列表
就是传说中的String... str应用于参数个数或者类型未知的场合
<!--[if !supportLists]-->u
<!--[endif]-->固定参数与可变参数的结合
<!--[if !supportLists]-->u
<!--[endif]-->可变参数列表的重载
<!--[if !supportLists]-->u
<!--[endif]-->非重载的情况,可变参数列可以输入空参数;有重载的情况不能输入空参数
.enum类型
没什么好讲的这个,这个以后再聊
这一章是我学得最累的,太多东西需要记了,哎
还有几点没有明白的地方,1.初始化顺序,比如说静态块什么的,还有构造器,main方法,他们的执行顺序是怎么样的
2.可变参数列表,类型可以使随便一个类的类型吗,比如我有一个dog类,参数可以是dog... d
3.a类调用b类的c方法来改变a类中int d变量的值,为什么不成功
4构造器为什么可以使用非静态方法或者变量,有些书说构造器不是静态方法...
针对以上问题,我特地去问了老师,查了资料,也弄明白了差不多
1.初始化顺序是这样的静态变量 静态初始化块 变量 初始化块 构造器 静态方法 普通方法,注:main方法是程序的入口,但是没有生成对象的,只是调用了main方法而已
注:若是父类和子类,那么顺序是这样的:
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
2.我个人觉得是什么类型都可以吧,应该就和普通参数一样,不同的地方就是因为它长度可以变化..这一点不确定.
注:我认为基本类型是为了兼容c而出现的,听说java 9将不会有基本类型,总之可以说object是类的老祖宗,但是和基本类型这一部分是分开的,基本类型不是object的子类...
3.其实是一个很基础的问题,呵呵,基础不扎实我,因为java的参数传递都是以传值的方式,所以传入的是a的copy,若是基本类型,则传入的是其copy,那么肯定就无法改变啦,若是引用,传入的是引用的copy,那么意思就是指向同一个地方,那么就可以改变,所以说要改变可以使用基本类型的包装类
4.我觉得构造器虽然是静态方法,但它和具体对象相关,所以可以访问普通成员变量和非静态方法,这是老师给我的答复,不过针对网上说构造器不是静态方法,这一点待以后再讨论,有想法的同志可以留回复,大家一起讨论
http://blog.sina.com.cn/s/blog_6fb65ce90100oy76.html
注:java的垃圾回收器 引用网络资源http://www.cnblogs.com/laoyangHJ/articles/java_gc.html
这篇写得很详细,可惜图挂了
垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再使用的对象。GC通过确定对象是否被活动对象引用来确定是否收集该对象。GC首先要判断该对象是否是时候可以收集。两种常用的方法是引用计数和对象引用遍历。
引用计数收集器
引用计数是垃圾收集器中的早期策略。在这种方法中,堆中每个对象(不是引用)都有一个引用计数。当一个对象被创建时,且将该对象分配给一个变量,该变量计数设置为1。当任何其它变量被赋值为这个对象的引用时,计数加1(a = b,则b引用的对象+1),但当一个对象的某个引用超过了生命周期或者被设置为一个新值时,对象的引用计数减1。任何引用计数为0的对象可以被当作垃圾收集。当一个对象被垃圾收集时,它引用的任何对象计数减1。
优点:引用计数收集器可以很快的执行,交织在程序运行中。对程序不被长时间打断的实时环境比较有利。
缺点: 无法检测出循环引用。如父对象有一个对子对象的引用,子对象反过来引用父对象。这样,他们的引用计数永远不可能为0.
跟踪收集器
早期的JVM使用引用计数,现在大多数JVM采用对象引用遍历。对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集。在对象遍历阶段,GC必须记住哪些对象可以到达,以便删除不可到达的对象,这称为标记(marking)对象。
下一步,GC要删除不可到达的对象。删除时,有些GC只是简单的扫描堆栈,删除未标记的未标记的对象,并释放它们的内存以生成新的对象,这叫做清除(sweeping)。这种方法的问题在于内存会分成好多小段,而它们不足以用于新的对象,但是组合起来却很大。因此,许多GC可以重新组织内存中的对象,并进行压缩(compact),形成可利用的空间。
为此,GC需要停止其他的活动活动。这种方法意味着所有与应用程序相关的工作停止,只有GC运行。结果,在响应期间增减了许多混杂请求。另外,更复杂的 GC不断增加或同时运行以减少或者清除应用程序的中断。有的GC使用单线程完成这项工作,有的则采用多线程以增加效率。
一些常用的垃圾收集器
(1)标记-清除收集器
这种收集器首先遍历对象图并标记可到达的对象,然后扫描堆栈以寻找未标记对象并释放它们的内存。这种收集器一般使用单线程工作并停止其他操作。并且,由于它只是清除了那些未标记的对象,而并没有对标记对象进行压缩,导致会产生大量内存碎片,从而浪费内存。
(2)标记-压缩收集器
有时也叫标记-清除-压缩收集器,与标记-清除收集器有相同的标记阶段。在第二阶段,则把标记对象复制到堆栈的新域中以便压缩堆栈。这种收集器也停止其他操作。
(3)复制收集器
这种收集器将堆栈分为两个域,常称为半空间。每次仅使用一半的空间,JVM生成的新对象则放在另一半空间中。GC运行时,它把可到达对象复制到另一半空间,从而压缩了堆栈。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。并且对于指定大小堆来说,需要两倍大小的内存,因为任何时候都只使用其中的一半。
(4) 增量收集器
增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾,也可理解为把堆栈分成一小块一小块,每次仅对某一个块进行垃圾收集。这会造成较小的应用程序中断时间,使得用户一般不能觉察到垃圾收集器正在工作。
(5)分代收集器
复制收集器的缺点是:每次收集时,所有的标记对象都要被拷贝,从而导致一些生命周期很长的对象被来回拷贝多次,消耗大量的时间。而分代收集器则可解决这个问题,分代收集器把堆栈分为两个或多个域,用以存放不同寿命的对象。JVM生成的新对象一般放在其中的某个域中。过一段时间,继续存在的对象(非短命对象)将获得使用期并转入更长寿命的域中。分代收集器对不同的域使用不同的算法以优化性能。
并行收集器
并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。在多CPU机器上使用多线程技术可以显著的提高java应用程序的可扩展性。
最后,贴出一个非常简单的跟踪收集器的例图,以便大家加深对收集器的理解:
跟踪收集器图例
使用垃圾收集器要注意的地方
下面将提出一些有关垃圾收集器要注意的地方,垃圾收集器知识很多,下面只列出一部分必要的知识:
(1)每个对象只能调用finalize( )方法一次。如果在finalize( )方法执行时产生异常(exception),则该对象仍可以被垃圾收集器收集。
(2)垃圾收集器跟踪每一个对象,收集那些不可触及的对象(即该对象不再被程序引用 了),回收其占有的内存空间。但在进行垃圾收集的时候,垃圾收集器会调用该对象的finalize( )方法(如果有)。如果在finalize()方法中,又使得该对象被程序引用(俗称复活了),则该对象就变成了可触及的对象,暂时不会被垃圾收集了。但是由于每个对象只能调用一次finalize( )方法,所以每个对象也只可能 "复活 "一次。
(3)Java语言允许程序员为任何方法添加finalize( )方法,该方法会在垃圾收集器交换回收对象之前被调用。但不要过分依赖该方法对系统资源进行回收和再利用,因为该方法调用后的执行结果是不可预知的。
(4)垃圾收集器不可以被强制执行,但程序员可以通过调研System.gc方法来建议执行垃圾收集。记住,只是建议。一般不建议自己写System.gc,因为会加大垃圾收集工作量。
详解Java GC的工作原理
概要: JVM内存结构由堆、栈、本地方法栈、方法区等部分组成,另外JVM分别对新生代和旧生代采用不同的垃圾回收机制。
1. 首先来看一下JVM内存结构,它是由堆、栈、本地方法栈、方法区等部分组成,结构图如下所示。
1)堆
所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。堆被划分为新生代和旧生代,新生代又被进一步划分为Eden和Survivor区,最后Survivor由FromSpace和ToSpace组成,结构图如下所示:
新生代。新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例旧生代。用于存放新生代中经过多次垃圾回收仍然存活的对象
2)栈
每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果
3)本地方法栈
用于支持native方法的执行,存储了每个native方法调用的状态
4)方法区
存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。JVM用持久代(PermanetGeneration)来存放方法区,可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。介绍完了JVM内存组成结构,下面我们再来看一下JVM垃圾回收机制。
2. JVM垃圾回收机制
JVM分别对新生代和旧生代采用不同的垃圾回收机制
新生代的GC:
新生代通常存活时间较短,因此基于Copying算法来进行回收,所谓Copying算法就是扫描出存活的对象,并复制到一块新的完全未使用的空间中,对应于新生代,就是在Eden和FromSpace或ToSpace之间copy。新生代采用空闲指针的方式来控制GC触发,指针保持最后一个分配的对象在新生代区间的位置,当有新的对象要分配内存时,用于检查空间是否足够,不够就触发GC。当连续分配对象时,对象会逐渐从eden到survivor,最后到旧生代,
用javavisualVM来查看,能明显观察到新生代满了后,会把对象转移到旧生代,然后清空继续装载,当旧生代也满了后,就会报outofmemory的异常,如下图所示:
在执行机制上JVM提供了串行GC(SerialGC)、并行回收GC(ParallelScavenge)和并行GC(ParNew)
1)串行GC
在整个扫描和复制过程采用单线程的方式来进行,适用于单CPU、新生代空间较小及对暂停时间要求不是非常高的应用上,是client级别默认的GC方式,可以通过-XX:+UseSerialGC来强制指定
2)并行回收GC
在整个扫描和复制过程采用多线程的方式来进行,适用于多CPU、对暂停时间要求较短的应用上,是server级别默认采用的GC方式,可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4来指定线程数
3)并行GC
与旧生代的并发GC配合使用
旧生代的GC:
旧生代与新生代不同,对象存活的时间比较长,比较稳定,因此采用标记(Mark)算法来进行回收,所谓标记就是扫描出存活的对象,然后再进行回收未被标记的对象,回收后对用空出的空间要么进行合并,要么标记出来便于下次进行分配,总之就是要减少内存碎片带来的效率损耗。在执行机制上JVM提供了串行GC(SerialMSC)、并行GC(parallelMSC)和并发GC(CMS),具体算法细节还有待进一步深入研究。
以上各种GC机制是需要组合使用的,指定方式由下表所示:
java 美女5 最喜欢的美女
分享到:
相关推荐
《Thinking in Java》是一本深度解析Java编程语言的经典著作,其深入浅出的讲解和丰富的实例使得读者能够全面理解Java的精髓。以下是对书中部分关键知识点的总结: 1. **Java 泛型**:泛型是Java SE 5.0引入的重要...
### Thinking in Java 读书笔记知识点总结 #### 一、万事万物皆对象 1. **对象存储位置** - **寄存器**:程序无法直接控制。 - **栈(Stack)**:存储基本类型数据和对象引用,但对象本身不在此处。 - **堆(Heap)...
### Thinking in Java 自学笔记——第二章 一切皆对象 #### 重要概念解析 ##### 2.1 用引用操纵对象 在Java中,一切都被视为对象,这意味着无论是字符串、数字还是其他数据类型都可以被视为对象来进行操作。当...
4.4 Foreach语法 4.5 return 4.6 break和 continue 4.7 臭名昭著的“goto” 4.8 switch 4.9 总结 第5章 初始化与清理 5.1 用构造器确保初始化 5.2 方法重载 5.2.1 区分重载方法 5.2.2 涉及基本类型的重载 5.2.3 以...
Thinking in Java 自学笔记——第一章 对象导论 本章节总结了面向对象程序设计(Object-oriented Programming, OOP)的基本概念和原则,以帮助读者更好地理解 Java 编程语言。以下是对标题、描述、标签和部分内容的...
《王者归来之Thinking in Java读书笔记》是对Bruce Eckel的经典之作《Thinking in Java》第四版的深度学习与总结。这本书是Java程序员的必备参考书,它深入浅出地阐述了Java语言的核心概念和技术,旨在帮助读者理解...
《Thinking in Java》第四版由布鲁斯·埃克尔(Bruce Eckel)撰写,他是MindView公司的总裁。这本书被广泛认为是学习Java编程语言的经典教材之一。从读者的反馈来看,《Thinking in Java》不仅覆盖了Java的核心概念...
根据提供的文件信息,以下是对文件《Thinking in Java 4th Edition Annotated Solutions Guide》中所包含知识点的详细解释: 首先,文件标题《Thinking in Java 4th Edition Annotated Solutions Guide》指出了这是...
### Thinking In Java 学习笔记知识点总结 #### 面向对象编程(OOP)的重要性及其影响 面向对象编程(OOP)在软件开发领域产生了深远的影响。它不仅提高了开发效率和降低了维护成本,还简化了设计流程,使得编程任务...
Thinking in java第三版中文版,第四版英文版以及对应的习题答案! 博文链接:https://easonfans.iteye.com/blog/456901
通过以上总结,我们可以更深入地理解《Thinking in Java》中关于构造器、方法重载、对象引用、静态与非静态方法调用、垃圾回收机制、对象初始化以及数组和可变参数列表等核心概念和技术细节。这些知识点对于深入理解...
《Thinking in Java》是Bruce Eckel的经典之作,第四版(TIJ4)更是Java程序员必读的书籍之一。这本书深入浅出地介绍了Java语言的核心概念和技术,包括面向对象编程、集合框架、多线程、网络编程等众多主题。源码是...
《Thinking in Java》是Bruce Eckel的经典之作,它深入浅出地介绍了Java语言的核心概念和技术。这本书的练习题是学习Java的重要组成部分,因为它们能够帮助读者巩固理论知识并提升实践能力。以下是对"Thinking in ...
《Thinking in Java》是一本备受推崇的Java编程教材,由Bruce Eckel撰写,被誉为Java学习者的必读之作。这本书深入浅出地介绍了Java语言的核心概念和技术,覆盖了从基础到高级的主题,对于有一定Java基础的读者来说...
《Thinking in Java》是 Bruce Eckel 编著的一本经典的Java编程教材,它深受程序员喜爱,被誉为学习Java的必备参考书。这本书全面深入地探讨了Java语言的核心概念和技术,不仅适合初学者,也对有经验的程序员提供了...
《Thinking in Java》是Bruce Eckel的经典之作,第四版涵盖了Java编程语言的广泛主题,适合初学者和有经验的程序员。这本书深入浅出地讲解了Java的核心概念和技术,旨在帮助读者建立坚实的编程基础,并理解面向对象...
《Thinking in Java》是Bruce Eckel的经典之作,被誉为学习Java编程的权威指南。该书以其深入浅出的方式,详尽地介绍了Java语言的核心概念和技术。第三版是此书的一个重要里程碑,它涵盖了Java语言的诸多关键特性,...
《Thinking in Java》是Bruce Eckel的经典之作,第四版更是被广大Java开发者视为学习和进阶的重要参考书籍。这本书深入浅出地介绍了Java语言的核心概念和技术,包括面向对象编程、集合框架、多线程、网络编程、GUI...
《Thinking in Java》是Bruce Eckel的经典编程教材,它深入浅出地介绍了Java语言的核心概念和技术。这本书以其详尽的解释、丰富的示例和实践性强的习题深受程序员喜爱。"Thinking in Java 习题答案"是配套的解答集,...
JAVA学习日记---Thinking in Java学习笔记 第5章总结 第五章 初始化与清理 5.1 用构造器确保初始化 1.构造器命名必须与类名相同 2.构造器也是方法,满足方法的各种特征,无参数的构造器称为默认构造器,默认构造...