在移动设备中调用System.gc() [英] Calling System.gc() in mobile

查看:115
本文介绍了在移动设备中调用System.gc()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须维护一个J2ME应用程序。应用程序中有很多 System.gc()。在调用System.gc()之前,所有属性都设置为null。设置属性为null是否有意义?调用 System.gc()是否合理?应该不是jvm在必要时调用垃圾回收器?

解决方案

所有对属性和System.gc进行置零的原因()调用肯定是对抗设备碎片的一部分。很容易地说,你不应该让自己陷入一个价值,你应该让它超出范围,实际上这是PC开发的适当方式。然而,移动领域是一个完全不同的动物,并且说你可以在有限的移动设备上以相同的方式处理内存管理,就像你在拥有可供使用的演出和演出RAM的PC上一样。

即使是现在,高端智能手机也有大约32-64MB的堆可用于J2ME应用程序。许多设备仍然在1-4MB左右,并且通常需要满足运营商规范,因此您需要针对更小的堆大小。 Razr只有800K的堆,并且仍然需要大多数运营商支持,因为他们的许多订户仍在使用该设备。



内存碎片发生的原因是即使一块内存不再被使用,它已被取消,但它在垃圾收集之前还不可用。大多数移动虚拟机仅在需要内存时才使用GC。所以当它最终运行GC时,堆可能会被分割成很小的内存块。当需要分配更大的内存块时,它将不能分配给较小的块。如果你有足够的这些小块来污染堆,而不是提供足够大的块来存放更大的对象,那么最终你会得到一个OutOfMemory异常,尽管看起来你可能拥有大量的内存。

例如,假设您创建一个需要50个字节的本地Object变量。接下来,您将分配一个成员变量,该变量将在需要200字节堆存在的应用程序的整个生命周期中持续存在。如果你一遍又一遍地执行这个过程,你可能会遇到这样的情况:你有成千上万个只有50个字节长度的内存块。因为你需要200字节的持久对象,你最终会被搞砸,并得到一个OutOfMemory异常。



现在如果你创建了相同的String对象,使用它,它自己并且调用System.gc()(也可以调用Thread.yield()为GC提供运行机会),然后可以使用这50个字节创建新的持久对象,避免碎片并避免最终出现OutOfMemory异常。



这是一个非常基本的例子,但是如果您在游戏应用程序中有很多大图像,您很快就会遇到这种情况移动领域。

最后一点,在BlackBerry设备中,您应该避免自己调用垃圾回收器,因为它非常复杂(它会为您整理堆积)。在大多数设备上,更复杂的操作会使速度慢得多(我们说每次运行数秒),而不是正常的宕机和肮脏的GC。

I have to maintain a J2ME application. There is a lot of System.gc() inside the application. Before calling System.gc() all the attributes are setted to null. Does setting attributes to null make sense? Does calling System.gc() make sense? Shouldn't the jvm call the garbage collector when is necessary?

解决方案

The reason for all the nulling of attributes and System.gc() calls is definitely part of a fight against device fragmentation. It's easy enough to say that you should never null a value yourself, that you should let it just go out of scope, and actually this is the appropriate way for PC development. However, the mobile space is a completely different animal and it would be naive to say that you can handle memory management the same way on a limited mobile device as you do on a PC that has gigs and gigs of RAM at its disposal.

Even now, the high-end smart phones have around 32-64MB of heap available to a J2ME application. Many devices are still around 1-4MB and often to meet carrier specification you will need to target even smaller heap sizes. The Razr only has 800K of heap and is still required to be supported by most carriers, due to the fact that so many of their subscribers still use the device.

Memory fragmentation happens because even though a block of memory is no longer in use, that it has been nullified, it is not yet available until it is garbage collected. Most mobile VMs only GC when memory is needed. So when it finally does run the GC, the heap could possibly be fragmented into tiny blocks of memory. When a larger block of memory needs to be allocated it will be unable to allocate to the smaller block. If you have enough of these smaller blocks polluting the heap, not supplying a block big enough for a larger object, eventually you will get an OutOfMemory exception, even though it may appear that you have tons of memory available.

For instance, imagine you create a local Object variable that requires 50 bytes. Next you allocate a member variable that will persist throughout the life of the application that requires 200 bytes of heap to exist. If you do this process over and over again, you could possibly get in the situation where you have thousands of blocks of memory that are only 50 bytes in length. Because you need 200 bytes for the persistent object, you will eventually be screwed and get an OutOfMemory exception.

Now if you created the same String object, used it, then nulled it yourself and called System.gc() (also you might want to call Thread.yield() to give the GC a chance to run) you would then have those 50 bytes available to create the new persistent object, avoid fragmentation and avoid the eventual OutOfMemory exceptions.

This is a very basic example, but if you have a lot of large images like in a game application, you run into this situation very quickly in the mobile space.

One last note, with BlackBerry devices you should avoid calling the garbage collector yourself as it is much more sophisticated (it will defrag the heap for you). Being more sophisticated makes it much slower (we're talking several seconds per run) than the normal down and dirty GCs on most devices.

这篇关于在移动设备中调用System.gc()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆