JAVA内存管理-创新互联
被问到有关Java内存管理的知识,所以要搜集整理一下了。开始之前,我们要明白一点,我们所使用的变量就是一块一块的内存空间!!
创新互联专注于企业成都全网营销、网站重做改版、建平网站定制设计、自适应品牌网站建设、H5页面制作、商城网站建设、集团公司官网建设、外贸网站制作、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为建平等各大城市提供网站开发制作服务。一、内存管理原理:
在java中,有java程序、虚拟机、操作系统三个层次,其中java程序与虚拟机交互,而虚拟机与操作系统间交互!这就保证了java程序的平台无关性!下面我们从程序运行前,程序运行中、程序运行内存溢出三个阶段来说一下内存管理原理!1、程序运行前:JVM向操作系统请求一定的内存空间,称为初始内存空间!程序执行过程中所需的内存都是由java虚拟机从这片内存空间中划分的。2、程序运行中:java程序一直向java虚拟机申请内存,当程序所需要的内存空间超出初始内存空间时,java虚拟机会再次向操作系统申请更多的内存供程序使用!3、内存溢出:程序接着运行,当java虚拟机已申请的内存达到了规定的大内存空间,但程序还需要更多的内存,这时会出现内存溢出的错误!至此可以看出,Java 程序所使用的内存是由 Java 虚拟机进行管理、分配的。Java 虚拟机规定了 Java 程序的初始内存空间和大内存空间,开发者只需要关心 Java 虚拟机是如何管理内存空间的,而不用关心某一种操作系统是如何管理内存的。 二、 RUNTIME 类的使用: Java 给我们提供了Runtime 类得到JVM 内存的信息方法名称 | 参数 | 作用 | 返回值 |
getRuntime | 无 | 获取 Runtime 对象 | Runtime 对象 |
totalMemory | 无 | 获取 JVM 分配给程序的内存数量 | long:内存数量 |
freeMemory | 无 | 获取 当前可用的内存数量 | long:内存数量 |
maxMemory | 无 | 获取 JVM 可以申请到的大内存数量 | long:内存数量 |
![](/upload/otherpic43/15221809-7388e0f04af546be8389ad67a3b44953.png)
public class Student {
String stuId;
String stuName;
int stuAge;
}
public class TestStudent {
public static void main(String[] args) {
Student s= new Student();
String name= new String("云鹤");
int a = 10;
char b = 'm';
s.stuId= "6363";
s.stuName= "刘德华";
s.stuAge= 25;
}
}
(1)类当然是存放在方法区里面的。
(2)Student s = new Student(); 这行代码就创建了两块内存空间,第一个在栈中,名字叫s,它就相当于指针类型的变量,我们看到它并不存放学生的姓名、年龄等具体的数值,而是存放堆中第二块内存的地址,第二块才存放具体的数值,如学生的编号、姓名、年龄等信息。 (3)int a = 10; 这是 基本数据类型 变量,具体的值就存放在栈中,并没有只指针的概念! 下图就是本例的内存布置图:![](/upload/otherpic43/18181328-68ab6274aff2476ab68555552b4a5dcd.png)
![](/upload/otherpic43/18181711-d81d43c4f1b14623922a6efe8f480f8e.png)
![](/upload/otherpic43/18182002-69f3583b0ebc4154a733444b124b2b46.png)
![](/upload/otherpic43/18182233-54643c478a7e4d69bf1e63f6f79cc877.png)
public class TestArray {
void change(int[] arr) {
for(int i=0;i
输出结果如下:
方法调用前:
1234
方法体内修改值后:
1000210004
方法调用后:
1000210004
数组实际上也是引用类型,在调用函数的过程中改变了其值。
(2)特例:String
public class TestString {
void change(String str) {
str= "吴奇隆";
System.out.println("方法体内修改值后:" + str);
}
public static void main(String[] args) {
String name= "歌星";
TestString testString= new TestString();
System.out.println("方法调用前:" + name);
testString.change(name);
System.out.println("方法调用后:" + name);
}
结果:
方法调用前:歌星
方法体内修改值后:吴奇隆
方法调用后:歌星
分析:
上例中,虽然参数String 是引用数据类型,但其值没有发生改变,这是因为String 类是final 的,它是定长,不允许对其进行改变,而StringBuffer(多线程下使用性能优)和StringBuilder(单线程下面使用性能优)是可以改变的。如果这里用StringBuffer和SringBuiler替代,结果和Array的使用一样,中间结果会被改变。 我们看初始情况,即String name = "歌星";这行代码运行 完,如下图:![](/upload/otherpic43/18184936-033828cee00f4b21909d0d519a3f0d91.png)
![](/upload/otherpic43/18185122-0aa505d4a9c4477a91169469855483f0.png)
![](/upload/otherpic43/18190244-b144c7cb5f544608b26eee08d738f2a4.png)
![](/upload/otherpic43/18190359-c49b882caa554518b8125e0b4ad6a3d7.png)
public class TestChange {
void change(Student stu1, Student stu2) {
stu1.stuAge++;
stu2.stuAge++;
Student stu= stu1;
stu1= stu2;
stu2= stu;
}
public static void main(String[] args) {
Student z= new Student();
z.stuName= "张信哲";
z.stuAge= 40;
Student r= new Student();
r.stuName= "任贤齐";
r.stuAge= 30;
System.out.println("交换前z: "+z.stuName+" "+z.stuAge);
System.out.println("交换前r: "+r.stuName+" "+r.stuAge);
TestChange testChange= new TestChange();
testChange.change(z, r);
System.out.println("交换后z: "+z.stuName+" "+z.stuAge);
System.out.println("交换后r: "+r.stuName+" "+r.stuAge);
}
}
运行结果:
交换前z: 张信哲 40
交换前r: 任贤齐30
交换后z: 张信哲41
交换后r: 任贤齐31
![](/upload/otherpic43/18221625-221ae5850e8d48bb99a5ab03d6eddfb7.png)
分享题目:JAVA内存管理-创新互联
网站网址:http://myzitong.com/article/ccscgg.html