盒子
盒子
Posts List
  1. 前言
  2. Java中对象的生命周期
  3. Java中的内存管理
  4. Java中常见的设计模式
  5. 总结

Android 学习之路--Java基础(四)

作者Talent•C
转载请注明出处

前言

今天是学习Java的第四天,每天抽出一点时间学习知识,有时也会感觉很累,但过后会觉得很充实,在学习新知识的同时也会对老知识进行巩固,总之坚持下来,就会有或多或少的收获;今天的学习目标是,Java中对象的生命周期、内存管理、Java中常见的设计模式。

Java中对象的生命周期

1. 创建阶段(Created)

  • 为对象分配存储空间;
  • 开始构造对象;
  • 从父类到子类对static成员进行初始化;
  • 父类成员变量按照顺序初始化,递归调用父类的构造方法;
  • 子类成员变量按照顺序初始化,子类构造方法调用;
  • 一旦对象被创建,并有某个引用指向它,这个对象的状态就切换到了应用阶段(In Use);

2. 应用阶段(In Use)
对象至少被一个强引用持有并且对象在作用域内。

3. 不可见阶段(Invisible)
程序本身不再持有该对象的任何强引用,但是这些引用可能还存在着;一般具体是指程序的执行已经超过该对象的作用域了。

4. 不可达阶段(Unreachable)
该对象不再被任何强引用所持有;可能仍被JVM等系统下的某些已经装载的惊天变量或者线程或JNI所持有,这些特殊的强引用被称为GC root,这种情况容易导致内存泄露,无法被回收。

5. 收集阶段(Collected)
对象不可达,并且GC已经准备好对该对象占用的内存空间重新分配的时候,处于手机阶段。
如果重写了finazlie()方法,则会去执行该方法。尽量不要重写finazlie()方法,因为有可能影响JVM的对象分配与回收速度或者可能造成该对象的再次复活。

6. 终结阶段
当对象执行完finalize()方法之后,仍然处于不可达状态时,则该对象进入终结阶段。在这个阶段,内存空间等待GC进行回收。

7. 对象空间的重新分配
GC对该对象占有的内存空间进行回收或者再分配,该对象彻底消失。

Java中的内存管理

1.java是如何管理内存的?
Java的内存管理就是对象的分配和释放问题。(两部分)
分配: 内存的分配是由程序完成的,程序员需要通过关键字 new 为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。
释放: 对象的释放是由垃圾回收机制决定和执行的,这样做确实简化了程序员的工作。但同时,它也加重了JVM的工作。因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。

2.什么叫java的内存泄露?
Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连(也就是说仍存在该内存对象的引用);其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。

3.JVM的内存区域组成:
Java把内存分两种:一种是 栈内存,另一种是 堆内存

  • 在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;
  • 堆内存用来存放由 new 创建的对象和数组以及对象的实例变量 在函数(代码块)中定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由 Java虚拟机 的自动垃圾回收器来管理。

堆和栈的优缺点:
堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。
缺点就是要在运行时动态分配内存,存取速度较慢; 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。另外,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

更深层次的Java内存管理这里就不介绍了,感兴趣的可以参考下面的文章
Java 内存管理详解

Java中常见的设计模式

设计模式(Design Patterns),设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。

设计模式的分类
总体来说设计模式分为三大类:

创建型模式,共五种: 工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种 适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种 策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

还有两类: 并发型模式和线程池模式。

下面我们简单看一下几个常用的设计模式
1.单例模式
该模式主要目的是使内存中保持1个对象。
代码示例:

方案一
public class Singleton
{
//将自身的实例对象设置为一个属性,并加上Static和final修饰符
private static final Singleton instance = new Singleton();
private Singleton()
{
//将构造方法设置成私有形式
}
public static Singleton getInstance() {
//通过一个静态方法向外界提供这个类的实例
return instance;
}
}
方案二
public class Singleton
{
private static Singleton instance = null;
public static synchronized Singleton getInstance()
{
if (instance == null){
instance = new Singleton();
}
return instance;
}
}

以上两种方案都可以实现単例,个人比较喜欢第一种。

2.工厂模式
该模式主要功能是统一提供实例对象的引用。
代码示例:

Apple手机通过工厂模式生产,同时ApplePhone实现接口 Phone
//接口类 Phone
public interface Phone {
public String getPhoneMode();
}
//苹果手机类 ApplePhone 实现接口 Phone
public class ApplePhone implements Phone {
private String phone_Mode;
public ApplePhone()
{
phone_Mode = “我是 iphone 系统 iOS 10.0”;
}
public String getPhoneMode ()
{
return phone_Mode;
}
}
//工厂类 Factory 负责创建 苹果手机 以后可以创建安卓手机等
public class Factory
{
public ApplePhone getApplePhone()
{
ApplePhone aPhone = new ApplePhone();
return aPhone;
}
}
//测试使用代码
Factory f = new Factory(); //初始化工厂
String phoneMode = f.getApplePhone().getPhoneMode(); //生产苹果手机并获取手机型号
System.out.print(“工厂模式创建的apple 型号:” + phoneMode); //输出生产的手机型号信息
输出结果:
工厂模式创建的apple 型号:我是 iphone 系统 iOS 10.0

这个是最简单的例子了。

4.观察者模式
观察者模式又称为订阅—发布模式,在此模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。
代码示例:

观察者代码示例
public class Watcher implements java.util.Observer
{
public void update(java.util.Observable obj, Object arg){
System.out.println(“观察者接收消息, count is “ + ((Integer) arg).intValue());
}
}
//被观察的代码示例
public class BeingWatched extends java.util.Observable
{
public void counter(int period) {
for(; period>=0; period– ) {
setChanged();
notifyObservers(new Integer(period));
try {
Thread.sleep(100);
} catch( InterruptedException e) {
System.out.println(“Sleep interrupeted” );
}
}
}
}
//测试代码
BeingWatched beingWatched = new BeingWatched();//受查者
Watcher watcher = new Watcher();//观察者
beingWatched.addObserver(watcher);
beingWatched.counter(10);
输出结果:
观察者接收消息, count is 10
观察者接收消息, count is 9
观察者接收消息, count is 8
观察者接收消息, count is 7
观察者接收消息, count is 6
观察者接收消息, count is 5
观察者接收消息, count is 4
观察者接收消息, count is 3
观察者接收消息, count is 2
观察者接收消息, count is 1
观察者接收消息, count is 0

关于Java中的设计模式这里就介绍这三个吧,如果大家兴趣可以查一查资料。

总结

昨天忙了一天,被临时分配了一个任务,很简单的任务,只是用一个Activity实现一个简单的的UI页面,一个初级的安卓工程师也就半天就可以搞定的界面;而作为一个安卓开发初学者的我,居然搞了一天,不过还是很有收获的,在这之前完完全全没有接触过安卓,就连安卓系统都是没怎么接触过,昨天整个人都要发疯了,中途也想过要放弃了(毕竟我是帮忙的),不过我最后还是坚持下来了完成了开发工作,自己感觉到很有成就感;也希望大家在遇到挫折时能坚持住,不管生活还是工作只要坚持就会成功。最后还是要感谢我媳妇对我鼓励,哈哈~~~ 总体来说我的Java基础学习基本告一段落了,比预期的要早一周的时间;明天开始进入第二阶段:了解Android系统及Android studio 开发环境。

最后允许我吐槽一下, 由于之前我做iOS开发公司配备的Mac book pro 使我成为了公司最有逼格的Android开发工程师,同时也是最痛苦的工程师,笔记本的磁盘居然120GB的,每次运行 Android studio 都需要清一下缓存。蛋疼的清缓存之路开启了….吐槽完毕。

支持一下
扫一扫,支持Talent•C