2015.09.01 Java 学习笔记—内存分析精华
2015-09-02 08:47
633 查看
掌握以下内容足以够以后学习所用,很好,很详细,一定吃透
栈内存:保存堆内存对应的地址数据,如果想要简单的理解,就将说明为对象的名称.
堆内存:保存真正有用的数据:指的是对象的属性内容,每一块堆内存都是一块内存地址的信息.
关键字new相当于计算机在内存之中自动开辟一块新的堆内存空间, 开辟完之后分配的是类里属性的默认值
对象只有实例化之后才可以使用,如果使用了未实例化的对象,一定会出现NullPointerExceptiong,而此异常只要是你从事开发工作,一定会一直陪伴这你, 特别需要提醒的是,每当使用了关键字new操作的时候都会分配新的堆内存空间,所以如果现在实例化了两个对象呢?
在日后的开发中,需要开辟新的堆内存空间,那么就是用关键字new
对象的真实数据都保存在堆内存之中,所以所谓的引用关系,指的就是同一块堆内存空间被不同的栈所指向
所以在实际的开发当中尽量不要产生无用的对内存空间,所有无用的堆内存空间最终都会被gc定期回收
2.成员变量和局部变量
成员变量包含:实例变量和类变量.(系统会为成员变量执行默认初始化)
实例变量:从有实例开始,实例变量就存在了,实例被销毁,实例变量销毁.
类变量:从有类开始,类变量就存在,一个jvm 里类信息只有一个,每个jvm 最多值加载一个类一次,系统就为该实例分配一块内存
Java程序不允许直接访问堆内存中的对象,只能通过该对象的引用操作该对象
只要你用这个类声明变量,或者创建实例或者调用这个类的静态方法或静态field都是用到了这个类
局部变量必须由程序员来初始化,系统不会对局部变量初始化,局部变量存放在相应方法栈中
内存分析基础知识
栈内存和堆内存栈内存:保存堆内存对应的地址数据,如果想要简单的理解,就将说明为对象的名称.
堆内存:保存真正有用的数据:指的是对象的属性内容,每一块堆内存都是一块内存地址的信息.
关键字new相当于计算机在内存之中自动开辟一块新的堆内存空间, 开辟完之后分配的是类里属性的默认值
对象只有实例化之后才可以使用,如果使用了未实例化的对象,一定会出现NullPointerExceptiong,而此异常只要是你从事开发工作,一定会一直陪伴这你, 特别需要提醒的是,每当使用了关键字new操作的时候都会分配新的堆内存空间,所以如果现在实例化了两个对象呢?
在日后的开发中,需要开辟新的堆内存空间,那么就是用关键字new
对象的真实数据都保存在堆内存之中,所以所谓的引用关系,指的就是同一块堆内存空间被不同的栈所指向
所以在实际的开发当中尽量不要产生无用的对内存空间,所有无用的堆内存空间最终都会被gc定期回收
2.成员变量和局部变量
成员变量包含:实例变量和类变量.(系统会为成员变量执行默认初始化)
实例变量:从有实例开始,实例变量就存在了,实例被销毁,实例变量销毁.
类变量:从有类开始,类变量就存在,一个jvm 里类信息只有一个,每个jvm 最多值加载一个类一次,系统就为该实例分配一块内存
Java程序不允许直接访问堆内存中的对象,只能通过该对象的引用操作该对象
只要你用这个类声明变量,或者创建实例或者调用这个类的静态方法或静态field都是用到了这个类
局部变量必须由程序员来初始化,系统不会对局部变量初始化,局部变量存放在相应方法栈中
先掌握一段简单程序内存分析
package com.buaa.day3; /*执行详解: * Test test = new Test(); * 首先在main方法栈内定义了一个局部变量test, * 接着在堆内存里产生Test对象,局部变量test指向此对象 * 接着int date = 9; * 在main方法栈中创建局部变量 date 值为9 * ************************************************ * * BirthDate d1= new BirthDate(7,7,1970); * 首先BirthDate d1,在stack中创建局部变量d1 , * 接着public BirthDate(int d, int m, int y) {day = d; month = m; year = y; }, * 在stack里临时产生局部变量 d, m, y * 接着new BirthDate(7,7,1970),将参数传给在堆内存创建BirthDate对象,局部变量 d, m, y消失 * 接着d1指向BirthDate对象(即d1存了可以找到BirthDate对象在堆内存的地址) * ************************************************ * * test.change1(date); * i 的值的变化是先变成9,然后继续执行变成1234,但是由于i是局部变量,当方法执行结束以后i的值自动消失, * 所以date的值依然是9没有改变 * ************************************************ *test.change2(d1); *目的是为了改变d1指向堆内存里的值 *首先test.change2(d1);把d1传进来,d1的值传给处在stack里的局部变量b,b指向了d1指向的堆内存对象值。 *接着 *public void change2(BirthDate b) {//b此时是局部变量,规定传入的参数必须是BirthDate的一个引用 *b = new BirthDate(22,2,2004);//创建对象后b不指向d1对象的内存堆,指向对象b 的内存堆 *方法调用完毕时,b这个局部变量消失,指向对象的引用就消失了,堆内存里22,2,2004内容无栈指针,所以会被垃圾回收机制回收 *故不能达到目的} ************************************************* * *test.change3(d2); *public void change3(BirthDate b) {b.setDay(22);} 局部变量b指向了d2指向的堆内存 *接着调用public void setDay(int d) {day = d;}此时在方法栈里产生d局部变量,将d2堆内存里的day的值传参为22,此时实现改变堆内存的对象的值 * * * * */ public class Test{ public static void main(String args[]){ Test test = new Test(); int date = 9; BirthDate d1= new BirthDate(7,7,1970); BirthDate d2= new BirthDate(1,1,2000); test.change1(date); test.change2(d1); test.change3(d2); System.out.println("date=" + date); d1.display(); d2.display(); } public void change1(int i){i = 1234;} public void change2(BirthDate b) {b = new BirthDate(22,2,2004);} public void change3(BirthDate b) {b.setDay(22);} } class BirthDate { private int day; private int month; private int year; public BirthDate(int d, int m, int y) {day = d; month = m; year = y; } public void setDay(int d) {day = d;} public void setMonth(int m) {month = m;} public void setYear(int y) {year = y;} public int getDay() {return day;} public int getMonth() {return month; } public int getYear() {return year; } public void display() {System.out.println(day + " - " + month + " - " + year);} } /*执行结果: date=9 7 - 7 - 1970 22 - 1 - 2000 */
接着掌握这段相对复杂的程序内存分析
package com.buaa.day3; import static java.lang.System.*; /*程序解读: * Circle c1 = new Circle(new Point(1.0,2.0), 2.0); * 首先执行Circle c1 ,c1是一个引用类型的变量,所以给它分配一块栈内存存放一个Circle对象的引用(也就是地址), * 接着new Point(1.0,2.0)在堆内存里分配Point对象, * 接着 Circle(Point p, double r) {//把圆心定到原点上。局部变量P指向Point对象, o = p; //让Circle对象的成员变量o指向指向Point对象的堆内存 radius = r; * 接着new Circle(new Point(1.0,2.0), 2.0);在堆内存分配Circle对象,并且让Circle对象的成员变量O指向point对象, * 这行代码的顺序之所以是这样是因为“=”的优先级比“new”的优先级低。 * * 执行结果:c1指向Circle对象的堆内存,Circle对象的成员变量O指向了point对象的堆内存 * * ***************************************************************** * * Circle c2 = new Circle(5.0); * 内存里又分配一块Circle对象,c2指向此对象 * Circle(double r) { o = new Point(0.0, 0.0);c2指向的Circle对象的成员变量O指向了point对象的堆内存,内容为0.0, 0.0 radius = r; } * * ***************************************************************** * * c1.getO().getX() * c1.getO() * public Point getO() { return o;//分配一块临时内存区域,此区域的值和O里的值一样,指向了Point对象的堆内存,内容为1.0,2.0 } * c1.getO().getX()返回1.0 * * * * * */ public class TestCircle { public static void main(String args[]) { Circle c1 = new Circle(new Point(1.0,2.0), 2.0); Circle c2 = new Circle(5.0); out.println("c1:("+c1.getO().getX()+","+c1.getO().getY()+"),"+c1.getRadius());//执行完之后main方法栈内存只剩下c1,c2 out.println("c2:("+c2.getO().getX()+","+c2.getO().getY()+"),"+c2.getRadius()); out.println("c1 area = "+c1.area()); out.println("c1 area = "+c2.area()); c1.setO(5,6); c2.setRadius(9.0); out.println("c1:("+c1.getO().getX()+"," +c1.getO().getY()+"),"+c1.getRadius()); out.println("c2:("+c2.getO().getX()+","+c2.getO().getY()+"),"+c2.getRadius()); out.println("c1 area = "+c1.area()); out.println("c1 area = "+c2.area()); //验证一个点是否在一个圆之内 Point p1 = new Point(5.2, 6.3); out.println(c1.contains(p1)); out.println(c1.contains(new Point(10.0,9.0))); } } class Point { private double x; private double y; Point(double x1, double y1) { x = x1; y = y1; } public double getX() { return x; } public double getY() { return y; } public void setX(double i) { x = i; } public void setY(double i) { y = i; } } class Circle { private Point o; private double radius; Circle(Point p, double r) {//把圆心定到原点上 o = p; radius = r; } Circle(double r) { o = new Point(0.0, 0.0); radius = r; } boolean contains(Point p) {//计算一个点是否在一个圆中 double x = p.getX() - o.getX(); double y = p.getY() - o.getY(); if(x*x + y*y > radius * radius) return false; else return true; } public void setO(double x, double y) { o.setX(x); o.setY(y); } public Point getO() { return o;//分配一块临时内存区域,此区域的值和O里的值一样,指向了Point对象的堆内存 } public double getRadius() { return radius;} public void setRadius(double r) { radius = r;} public double area() { return 3.14 * radius * radius; } } /*执行结果: c1:(1.0,2.0),2.0 c2:(0.0,0.0),5.0 c1 area = 12.56 c1 area = 78.5 c1:(5.0,6.0),2.0 c2:(0.0,0.0),9.0 c1 area = 12.56 c1 area = 254.34 true false */
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统