java内存控制和变量问题

来源:互联网 发布:java开发订单系统 编辑:程序博客网 时间:2024/04/29 23:23

提到java的内存问题,大家首先想到的可能是java的垃圾回收机制,因为大家可能会感觉java有垃圾回收机制,没有必要在乎内存问题,在我们普通学习,测试中,可能反映出的问题并不是很大,但是到了实际的开发中问题就会出来了,首先java的内存回收机制并不是让你完全不必考虑内存问题,要明确这一点,当然,博客后面我也会一步步的来解释这个问题。


java的内存管理:

内存分配:

当我们创建一个java对象的时候,JVM会为该对象分配内存空间。

(说JVM我又想扯一点了,可能会有读者对其并不了解,JVM Java Virtual Machine 懂点英文的话就知道了,java虚拟机,正是因为这种它,java才实现了跨平台的而无需像其他语言一样,在其它的平台上还需要重新编译)。

内存回收:

内存回收机制是JVM在后台开启一条线程,来处理一些失去了引用的对象,这也说明了一件问题,回收并不是凭空无损耗的就被回收掉了,需要回收的东西多了,线程的负担也就大了,程序的性能就降低了。


java中的变量类型

讲到对象和内存问题,首先要说的就是变量问题了,Java程序中变量分为成员变量和局部变量。

局部变量局部变量的作用时间是很短的,它们都被存在栈中。形参,方法内定义的变量,代码块中定义的变量,除了形参之外,这些变量在被定义的时候必须要进行显示初始化,如果不进行初始化的编译器将会报错,这正是java语言的一个特点了,这极大的提高了代码的安全性,因为局部变量是被放在栈中的,它的大小是不确定的,值也是系统随机为其进行分配的,所以说,如果为对其进行赋值的话,它的值将会是一个异常的值,可能会导致程序运行异常,甚至是崩溃,从这也看出来了java语言的严谨,尽管它并不是那么的优美。

(对于代码块的问题我将单独开一篇博客进行讲述,因为代码块涉及到四种形式和指向顺序的问题,此处暂不讲述)

成员变量:定义在类体中的变量,如果被static修饰之后,该变量则被称作静态变量或者是类变量,未被修饰的则是非静态变量或者是实例变量,static只能修饰这些类里的成员。


非法前向引用问题

这两种变量除了在生命周期上的不同之外,也就是内存回收的不同,说到内存,我们讲到的是两个方面的内容,另一个就是内存的分配问题,分配问题,大小上肯定是没有什么区分的,其区分就在分配时间上的了,正是因为这个分配问题导致了我们在平时coding中可能会出现的一个问题就是,非法前向引用问题,下面用代码展示一下吧。

//非法前向引用public class test {int num1 = num2 + 1;int num2 =3;}//非法前向引用public class test {static int num1 = num2 +2;static int num2 = 2;} //合法前向引用public class test {int num1 = num2 +1;static int num2=1; }

通过上面的例子我们就可以看出,初始化的过程中,静态变量是最先被初始化的,然后才是非静态变量,也就是实例变量。在XML语言中也是这样的,方法的话就没有这个问题出现。


实例变量和类变量的属性 

首先要从类说起,因为它们都是在类中的吗,在java虚拟机JVM上每一个类对应一个Class对象,因此在每一个类中的变量只需要一块空间,但是实例变量在每次被创建的时候,每次都要被开辟出一个空间,所以又回到了之前我们说的问题,那就是不要new一堆的对象出来,这样只会使你内存吃不消的,就好比你找了一堆的对象,那么你的钱包可能就要吃不消了,虽然你会淘汰掉一部分,但是淘汰也是一个过程,找个对象简单,甩掉可能没有这么简单,这就和java的垃圾回收机制似得,回收也是要有投入的,回收不好导致了内存泄露等问题出现直接就使你的程序蹦了,女朋友甩不好,很容易影响到你的终身大事,类变量的调用其实是最终是通用类来进行调用的而不是对象来直接进行访问的,这也就是java的一个缺陷,既然是类变量的东西为什么你特码的一个对象来操作了。

下面要讲的就是

实例变量的初始化

class WeChat {public WeChat (String name){this.name = name;}{name = "IT90s最前线 微信公众号";}String name = "表白大师";}
//当new一个对象出来时,name会是什么呢
WeChat wechat = new WeChat("摇滚英语");
</pre>执行过程中name的值是怎么变化的呢,搞清这一点,对实例化变量的初始化也就了解的够深了,<p></p><p><span style="font-size:18px"></span></p><pre name="code" class="java">name = “表白大师”;name = "摇滚英语";name = "IT90s最前线"
首先被调用的就是非静态的代码区,然后就是定义变量时的初始值,非静态代码区的执行顺序和定义变量时的执行顺序是相同的,构造则是最后执行的。












0 0
原创粉丝点击