作者garywine1201 (那是啥)
看板java
标题Re: [问题] JAVA String
时间Sat Jan 24 19:31:49 2009
※ 引述《sbrhsieh (sbr)》之铭言:
: ※ 引述《garywine1201 (那是啥)》之铭言:
: : 一般而言jvm会在某段时间过後对於记忆体进行清理
: : 但其清理的是程式在jvm中占用的记忆体量
: : 而非jvm在OS下的记忆体占用量
: : 可以看一下这边对於gc()函式的实验
: : http://www.devdaily.com/java/edu/pj/pj010008/pj010008.shtml
: : 摘录最後实验结果
: : free memory before creating array: 4054912
: : free memory after creating array: 3852496
: : free memory after running gc(): 4064184
: : 在实验开始之前,jvm可用记忆体为4054912
: : 这边指的是jvm在OS当中的占用量
: : 实验开始之後,jvm的记忆体配置为3852496
: : 但重新释放之後却使得记忆体可用为4064184
: : 这边会发现jvm多吃了OS一些空间
: 从这些数据怎麽可以推论出 JVM 从 OS 获得更多的记忆体空间?
: 这个测试程式执行 step 2 的时候,并不表示此时 JVM 管理的 heap 是 garbage-
: free,所以等到 step 5 之後 available heap 空间变多,不代表 JVM 向 OS 索取
: 更多的记忆体。
你说的没错 这些数据不足以得出我的推论
要得到这个推论 要有更进一步的实验 不过就算有实验 结论也仅止於我的猜测
我也说明了这是我的推测
这个实验由三个function所构成 他们的目的是这样的
http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html
freeMemory()
Returns the amount of free memory in the Java Virtual Machine.
gc()
Runs the garbage collector.
totalMemory()
Returns the total amount of memory in the Java virtual machine.
如你所说 呼叫free memory所得到的记忆体量应该不等於jvm记忆体量
所以要观察jvm的总记忆体占用必须呼叫totalmemory()这个函式
我对eatmemory这个函式进行修改 以取得三种不同的记忆体使用情况
1. 使用原本实验对记忆体进行50000阵列大小的宣告
2. 重复使用回圈呼叫eatmemory函式多达200次(事实上我尝试了20,30,100,结果相同)
3. 直接使eatmemory的阵列宣告等同200次的大小(200*50000)
对原本的函式而言 我在Mac powerbook上面跑,得到
1.
free memory before creating array: 1584824
total memory before creating array: 2031616
total memory after eatting memory: 2031616
free memory after creating array: 1642192
free memory after running gc(): 1843584
total memory after creating array: 2031616
2.
free memory before creating array: 1584784
total memory before creating array: 2031616
total memory after eatting memory: 2031616
free memory after creating array: 1442240
free memory after running gc(): 1843584
total memory after creating array: 2031616
3.
free memory before creating array: 1584824
total memory before creating array: 2031616
total memory after eatting memory: 42033152
free memory after creating array: 1843616
free memory after running gc(): 45973928
total memory after creating array: 46161920
从这边可以发现,jvm会有一个预设的记忆体初始大小 也就是default memory claim
从实验一可以发现 由於内部程式记忆体并未占用大於jvm可以负担的能力
所以jvm的记忆体占用始终如一
接着使用回圈进行函式宣告,这边发现跑完之後记忆体的总量是相同的
并没有因为你过多的宣告而使得记忆体需求上扬
这边显示了jvm内建垃圾蒐集的处理效率
当回圈往下跑时,之前没有使用的阵列在经过一个固定时间点之後会进行清理
所以虽然实验二的记忆体占用会比实验一多(用来储存最近几笔资料的额外空间)
但并没有让jvm向os要求任何记忆体
反观实验三
若你的程式一次性的呼叫大量的空间
并开始超出jvm的需求,jvm会直接向OS请求更多的记忆体空间(当然受限於最大值)
不过有趣的事情发生了,
在要求os提供记忆体之後,jvm的占用暴增到420...这很合理
但当我们gc并释放记忆体之後,jvm的记忆体占用并未稳定,而是向上提昇了一些
也就是说,当你在处理变数时,就算你的变数只有非常低的机率会有较大的信息值
(也就是熵值,占用bit数量的意思)
jvm一旦处理至这个变数,便会强迫自己增肥,而且会额外宣告空间以防止自己
out of memory exception
因此,在处理小程式且变数固定的情况下,jvm并不会扩张的太严重
但若你的程式有可能突然处理到较为复杂的变数
其就会强迫jvm进行一次增肥
而这个记忆体暂用量 会一直持续到你关闭程式为止
以目前的实验来看似乎是没有办法让jvm减瘦的
我想这好像解释了为什麽我使用netbeans的记忆体使用量总是越来越高
即使我把额外的编辑视窗都关了 情形依旧的原因
除了这个实验
其实我认为也还可以针对garbage collection的机制做出测试
观察其反应的周期
也许有时候因为垃圾蒐集的不够快,导致jvm自我增长也是有可能的
: : 因此对jvm进行free这个动作,并不会减少其耗用OS的资源能力
: : 因为jvm是自行控管记忆体配置的
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.64.235.79
3F:推 jtmh:跟我以前用 jEdit 的经验符合。 01/24 21:53