Java中一个奇怪的现象,请教达人

来源:百度知道 编辑:UC知道 时间:2024/05/28 07:27:07
小弟学习Java中,为了弄明白Java的内存管理机制,无意中发现个奇怪的现象.代码如下:
class test
{
public static void main(String[] args)
{
long i=Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
System.out.println("Begin Token Memory:"+i);
byte[][] aray=new byte[1000][4000];
// byte[] aray=new byte[4000000];
System.out.println("After the new Token Memory:"+(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()-i));
System.out.println("End Free Memory:"+(Runtime.getRuntime().freeMemory()));
}
}
目的是为了测出数组的大小.
测试数据如下
1:
byte[][] aray=new byte[100][2000];//占用206464字节的内存.
byte[][] aray=new byte[1000][200];//占用222816
这里就有了分歧,同样的逻辑空间,却占用了不同的内存大小.
2:
byte[][] aray=new byte[200][200];
占用37136字节.
申请了40000字节的空间,为何占用37137的空间呢?

这个我实在是理解不了,请高人指点.拜托了!

首先你打印的数据只是虚拟机当前内存情况,这个内存包括虚拟机运行的内存,所以不只是你数组的内存,第二点,java垃圾回收机制也有可能导致可用内存不一样。
最后分析你的数组。
byte[][] aray=new byte[100][2000];//占用206464字节的内存.
byte[][] aray=new byte[1000][200];//占用222816
数组在内存保存是连续的,而实际上程序运行时有内存碎片,虽然这部分碎片是空的如果你的数组列数大放不进去的话那这部分内存就等于是浪费了,所以[100][2000]这样的数组就容易被分配到那些内存碎片中去,开的新内存几句要少点,所以打印的数据显示用的内存要少。
当然这纯属个人分析,实际情况这3者结合起来就要复杂多了。
你的第二点,我这里在打印之前加了一个gc之后出现了更奇怪的现象,打印出负数了,可用内存在开了数组之后反而变多了。原因就是你前后两次的总内存是不一样的,totalMemory这个值都变大了。

public long totalMemory()返回 Java 虚拟机中的内存总量。此方法返回的值可能随时间的推移而变化,这取决于主机环境。
注意,保存任意给定类型的一个对象所需的内存量可能取决于实现方法。

最后:我觉得java内存机制千万不要像c那样死看内存的,只是在写程序时注意不要一次开出太多内存,就可以了,不要试图自己去管理内存,这样只会适得其反,不要刻意严格控制内存。

以上仅供参考!

我认为啊(不一定对)
在Java里面两位数组的意思是数组的数组,也就是说:比如
byte[][] aray=new byte[100][2000];这里aray数组变量存放的是数组byte[0]~byte[99]的首地址,同样的array[0]存放的是array[0][0]~array[0][199]的里面的首地址,所以array[0][0]~array[0][199]存放的是byte变量,数组byte[0]~byte[99]存放的是地址,地址占用的字节和byte占用的字节是不一样的,你两个数组地址数和byte变量数不一样,所以你两个数组占用的字节不