Unit03 - 对象内存管理 、 继承的意义(上)    

1.内存管理:由JVM来管理的
  1)堆:
    1.1)存储所有new出来的对象(包含成员变量)
    1.2)没有任何引用所指向的对象就是垃圾,
        垃圾回收器(GC)不定时清理垃圾,
        回收过程是透明的(看不到的),
        调用System.gc()建议GC尽快来回收
    1.3)成员变量的生命周期:
          创建对象时存在堆中,对象被回收时一并被回收
    1.4)内存泄露:不再使用的对象没有被及时的回收
                 建议:对象不再使用时及时将引用设置为null
  2)栈:
    2.1)用于存储正在调用中方法的所有局部变量(包括参数)
    2.2)调用方法时在栈中为该方法分配一块对应的栈帧,
        栈帧中存储的是方法中的所有局部变量(包括参数),
        方法调用结束时,栈帧被清除,局部变量一并被清除
    2.3)局部变量的生命周期:
          调方法时存在栈中,方法结束时与栈帧一起被清除
  3)方法区:
    3.1)用于存储.class字节码文件(包括方法)
    3.2)方法只有一份,
        通过this来区分具体的对象

2.继承:
  2.1)作用:实现代码的复用,避免代码的重复
  2.2)通过extends来实现继承
  2.3)父类:所有子类所共有的属性和行为
      子类:子类所特有的属性和行为
  2.4)子继承父后,子具有: 父类的+子类的
  2.5)一个父类可以有多个子类,
      一个子类只能有一个父类----单一继承
  2.6)继承具有传递性
  2.7)java规定,构造子类之前必须先构造父类
      若子类构造中不调用父类的构造,则默认super()调用父类的无参构造
      若子类构造中调了父类的构造,则不再默认提供
      super()调用父类的构造必须位于子类构造的第一句

3.super:指代当前对象的父类对象
  super的用法:
    1)super.成员变量名------访问父类的成员变量
    2)super.方法名()--------调用父类的方法
    3)super()---------------调用父类的构造方法

4.向上造型:
  1)父类型的引用指向子类的对象
  2)能点出来什么,看引用的类型

//老虎是动物
Animal o3 = new Tiger(); //向上造型

class Animal{ //动物类
}
class Tiger extends Animal{ //老虎类
}

JAVA内存变量:
编译期,只检查语法是否正确
编译错误,指的是语法错误

运行期,JVM登场----分配内存

变量----占用的是JVM的内存

JAVA垃圾管理:
没有任何引用所指向的对象
垃圾回收器(GC),不定时到内存堆中清理垃圾
并非看到垃圾就立刻清理

垃圾回收过程是透明的(看不到的)
System.gc()让内存回收尽量快一些

内存泄露:

    没有用的内存还没有被及时的回收
         若对象不用了,及时将引用设置为null

堆-1

堆-2

方法区

程序一:

package oo.day03;

public class Cell {
int row;
int col; Cell(int row,int col){
this.row = row;
this.col = col;
} String getCellInfo(){
return row+","+col;
} }

Cell.java

package oo.day03;

public class Tetromino {
Cell[] cells; //格子数组,成员变量
// Cell[] cells=null; //如果没有下面cells = new Cell[4];声明操作,T.java里面会报索引错误 Tetromino() {
cells = new Cell[4]; //创建格子数组对象 } void drop(){
for(int i=0;i<cells.length;i++){
this.cells[i].row++;
}
} void moveLeft(){
for(int i=0;i<cells.length;i++){
this.cells[i].col--;
}
} void moveRight(){
for(int i=0;i<cells.length;i++){
this.cells[i].col++;
}
} void print(){
for(int i=0;i<cells.length;i++){
String str =this.cells[i].getCellInfo();
System.out.println(str);
}
}
}

Tetromino.java

package oo.day03;

public class T extends Tetromino {
T(){
this(0,0);
} T(int row,int col){
//super(); //调用父类的无参构造---默认参数
cells[0] = new Cell(row,col); //创建格子
cells[1] = new Cell(row,col+1);
cells[2] = new Cell(row,col+2);
cells[3] = new Cell(row+1,col+1);
}
}

T.java

package oo.day03;

public class J extends Tetromino{
J(){
this(0,0);
} J(int n){
this(n,n);
} J(int row,int col){
this.cells[0] = new Cell(row,col);
this.cells[1] = new Cell(row,col+1);
this.cells[2] = new Cell(row,col+2);
this.cells[3] = new Cell(row+1,col+2);
}
}

J.java

package oo.day03;

public class O extends Tetromino{
O(){
this(0,0);
} O(int n){
this(n,n);
} O(int row,int col){
this.cells[0] = new Cell(row,col);
this.cells[1] = new Cell(row,col+1);
this.cells[2] = new Cell(row+1,col);
this.cells[3] = new Cell(row+1,col+1);
}
}

O.java

package oo.day03;

public class TJTest {

    public static void main(String[] args) {

//    T t = new T(2,5);
// printWall(t);
Tetromino o1 = new T(2,5); //02.-1 向上造型
printWall(o1); //传值 J j = new J(1,6); //02.-2
printWall(j); //向上造型,同时传值 }
//打墙+打T型-----方法二:
// public static void printWall(T tt){
public static void printWall(Tetromino tt){ //01. 向上造型
// public static void printWall(T tt){ //01. 向上造型
// public static void printWall(J tt){ //01. 向上造型
for(int i=0;i<20;i++){ //控制行
for(int j=0;j<10;j++){ //控制行个数0
boolean flag = false; //1.假设打-
// i = 2 j = 5
for(int k=0;k<tt.cells.length;k++){ //这里循环4次;
if(i==tt.cells[k].row&& j==tt.cells[k].col){ //这里只取一次正确结果,如果有else,把“-”也会打上
flag = true; //因为有四个格子,所以循环4次,这里只取对的那次,
break;
}
}
if(flag){
System.out.print("* ");
}else{
System.out.print("- ");
}
}
System.out.println();
} /* //打墙+打T型----方法一
public static void printWall(T tt){
for(int i=0;i<20;i++){
for(int j=0;j<10;j++){
if(i==tt.cells[0].row&&j==tt.cells[0].col
||
i==tt.cells[1].row&&j==tt.cells[1].col
||
i==tt.cells[2].row&&j==tt.cells[2].col
||
i==tt.cells[3].row&&j==tt.cells[3].col){
System.out.print("* ");
}else{
System.out.print("- ");
} }
System.out.println();
}*/
} }

TJTest.java

增加打印“I am a T”

package oo.day04;
//T型
public class T extends Tetromino{
T(){
this(0,0);
}
T(int row,int col){
super(); //调用父类的无参构造---默认的
super.cells[0] = new Cell(row,col); //创建格子对象
super.cells[1] = new Cell(row,col+1);
super.cells[2] = new Cell(row,col+2);
super.cells[3] = new Cell(row+1,col+1);
} void print(){ //输出4个格子的行列号
System.out.println("I am a T:");
super.print(); //调用父类的print()方法
}
}

程序二:(类继承的演示)

upTypeDemo.java

package oo.day03;

public class UpTypeDemo {
public static void main(String[] args) {
Eoo o1 = new Eoo();
o1.e = 1;
o1.show();
//o1.f = 2; //编译错误,父类不能访问子类 Foo o2 = new Foo();
o2.f = 1;
o2.test();
o2.e = 2; //正确,子类可以访问父类
o2.show(); //正确,子类可以访问父类 Eoo o3 = new Foo(); //向上造型,语法:父类名字,子类的名字;
o3.e = 1; //这不是造型,这是访问成员,访问东西
o3.show();
//o3.f = 2; //编译错误,能点出来什么,看引用类型
//o3对应的是Eoo类,所以只能使用Eoo下面的方法;
}
} class Eoo{ //Eoo是父类
int e;
void show(){}
} class Foo extends Eoo{ //Foo是子类,继承Eoo父类
int f;
void test(){}
}

课后作业:

1 简述JVM垃圾回收机制

参考答案

垃圾回收机制是Java提供的自动释放内存空间的机制。

垃圾回收器(Garbage Collection,GC)是JVM自带的一个线程,用于回收没有被引用的对象。

2 Java程序是否会出现内存泄露

参考答案

会出现内存泄漏,一般来说内存泄漏有两种情况。

一是在堆中分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉;

另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。

第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。

下面给出了一个简单的内存泄露的例子。在这个例子中,我们循环申请Object对象,并将所申请的对象放入一个List中,如果我们仅仅释放引用本身,那么List仍然引用该对象,所以这个对象对GC来说是不可回收的。代码如下所示:

        List list=new ArrayList(10);
for (int i=1;i<100; i++)
{
Object o=new Object();
list.add(o);
o=null;
} 此时,所有的Object对象都没有被释放,因为变量list引用这些对象。

3 JVM如何管理内存,分成几个部分?分别有什么用途?说出下面代码的内存实现原理:

    Foo foo = new Foo();
foo.f();

参考答案

JVM内存分为“堆”、“栈”和“方法区”三个区域,分别用于存储不同的数据。

堆内存用于存储使用new关键字所创建的对象;栈内存用于存储程序运行时在方法中声明的所有的局部变量;方法区用于存放类的信息,Java程序运行时,首先会通过类装载器载入类文件的字节码信息,经过解析后将其装入方法区。类的各种信息(包括方法)都在方法区存储。

    Foo foo = new Foo();
foo.f();

以上代码的内存实现原理为:

1.Foo类首先被装载到JVM的方法区,其中包括类的信息,包括方法和构造等。

2.在栈内存中分配引用变量foo。

3.在堆内存中按照Foo类型信息分配实例变量内存空间;然后,将栈中引用foo指向foo对象堆内存的首地址。

4.使用引用foo调用方法,根据foo引用的类型Foo调用f方法。

Unit03 - 对象内存管理 、 继承的意义(上)的更多相关文章

  1. Objective-C 【单个对象内存管理(野指针&内存泄露)】

    ------------------------------------------- 单个对象内存管理 (1)野指针 ①定义了一个指针变量,但是并没有赋初值,它随机指向一个东西 ②某指针变量指向的内 ...

  2. oc48--多个对象内存管理练习

    // // main.m // 多个对象内存管理练习 // // ARC是Xcode帮我们生成内存释放的代码,MRC是需要我买自己写retain和release.想研究内存管理只能在MRC,管理对象就 ...

  3. Objective-C 【多个对象内存管理(野指针&内存泄漏)】

    ------------------------------------------- 多个对象内存管理(野指针&内存泄漏) (注:这一部分知识请结合"单个对象内存管理"去 ...

  4. 【cocos2d-x 3.x 学习笔记】对象内存管理

    内存管理 内存管理一直是一个不易处理的问题.开发人员必须考虑分配回收的方式和时机,针对堆和栈做不同的优化处理,等等.内存管理的核心是动态分配的对象必须保证在使用完成后有效地释放内存,即管理对象的生命周 ...

  5. iOS 非ARC基本内存管理系列 2-多对象内存管理(3) 利用@property来自动管理内存

    iOS 基本内存管理-多对象内存管理(2)中可以看到涉及到对象的引用都要手动管理内存:每个对象都需要写如下代码 // 1.对要传入的"新车"对象car和目前Person类对象所拥有 ...

  6. 引用计数的cocos2dx对象内存管理和直接new/delete box2d对象内存管理冲突的解决方法

    转载请注明: http://blog.csdn.net/herm_lib/article/details/9316601 项目中用到了cocos2dx和box2d,cocos2dx的内存是基于引用计数 ...

  7. iOS 非ARC基本内存管理系列 2-多对象内存管理(2)

    /* 多对象内存管理: 以人拥有车为例涉及到@property底层set方法管理内存的实现 注意:人在换车的时候要进行当前传入的车和人所拥有的车进行判断 */ /******************* ...

  8. iOS 非ARC基本内存管理系列 2-多对象内存管理(1)

    单个对象的内存管理非常简单无非就是alloc对应release,retain对应release.但是如果涉及到很多对象,而且对象与对象有联系的时候该怎么去管理对象的内存呢. 比如同样一本书有好3个人购 ...

  9. oc45--多对象内存管理 优化

    // // main.m // Set方法的内存管理 #import <Foundation/Foundation.h> #import "Person.h" #imp ...

随机推荐

  1. Hadoop建立IPC连接和数据读写

    建立IPC连接 IPC Client通过调用getConnection获取IPC连接,具体流程图如下: 服务器端的IPC连接代码分散在Listener和Server.Connection中. List ...

  2. Codeforces Round #246 (Div. 2) A. Choosing Teams

    给定n k以及n个人已参加的比赛数,让你判断最少还能参加k次比赛的队伍数,每对3人,每个人最多参加5次比赛 #include <iostream> using namespace std; ...

  3. Codeforces Round #216 (Div. 2)A. Valera and Plates

    #include <iostream> using namespace std; int main(){ int n, m , k; cin >> n >> m & ...

  4. 20145330《Java程序设计》课程总结

    20145330第八周<Java学习笔记> 每周读书笔记汇总 第一周学习总结 第二周学习总结 第三周学习总结 第四周学习总结 第五周学习总结 第六周学习总结 第七周学习总结 第八周学习总结 ...

  5. GO语言练习:多返回值函数

    1.代码 2.运行 1.代码 package main import ( "fmt" "strconv" ) func getValue(n int) (flo ...

  6. JavaScript笔记——this的取值

    有关ECMAScript定义如何获取this请移步ECMAScript中关于如何获取this的定义 绝大多数情况下,函数的调用方式决定了this的取值 全局上下文 console.log(this = ...

  7. 详解CALayer 和 UIView的区别和联系

    详解CALayer 和 UIView的区别和联系   前言 前面发了一篇iOS 面试的文章,在说到 UIView 和 CALayer 的区别和联系的时候,被喵神指出没有切中要点,所以这里就 CALay ...

  8. gerrit使用教程

      注:使用时把“user”替换为自己的账号,例如 ueapp: ssh://huang.fei@10.0.64.16:29418/jonet2_0_app_ueapp.git 新的环境下需要先注册g ...

  9. web.xml的一份配置(备忘)

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java ...

  10. R中创建not-yet-evaluated对象

    create not-yet-evaluated object在R中创建 not-yet-evaluated(就是some code we will evaluated later!!)对象;然后执行 ...