「java中的oom」java中的oom是什么意思
本篇文章给大家谈谈java中的oom,以及java中的oom是什么意思对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
java oom异常怎么解决方案
在 Java中,JavaVM拥有自动管理内存的功能,Java的GC能够进行垃圾回收,但是Android中如果ImageView使用过多的Bitmap的话,经常会报OOM(内存溢出)。
造成内存溢出及解决方案:
1.使用BitmapFactory.decodeStream替代createBitmap方法
原因是该方法直读取图片字节,调用JNInativeDecodeAsset()来完成decode,无需再使用java层的createBitmap。
2.使用压缩读取技术
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imageSdUri, options);
final int height = options.outHeight;
final int width = options.outWidth;
options.inSampleSize = 1;
int w = 320;
int h = 480;
h = w*height/width;//计算出宽高等比率
int a = options.outWidth/ w;
int b = options.outHeight / h;
options.inSampleSize = Math.max(a, b);
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(imageSdUri, options);
3.及时释放Bitamp
Bitmap对象在不使用时,我们应该先调用recycle()释放内存,然后才它设置为null.虽然recycle()从源码上看,调用它应该能立即释放Bitmap的主要内存,但是测试结果显示它并没能立即释放内存。但是我它应该还是能大大的加速Bitmap的主要内存的释放。
oom的解决方法有哪些,请说明
1. 正确释放drawable的方式:
Bitmap bm = BitmapFactory.decodeResource(this.getResources(), R.drawable.splash);
BitmapDrawable bd = new BitmapDrawable(this.getResources(), bm);
mBtn.setBackgroundDrawable(bd);
来代替mBtn.setBackgroundResource(R.drawable.splash)。
销毁的时候使用:
BitmapDrawable bd = (BitmapDrawable)mBtn.getBackground();
mBtn.setBackgroundResource(0);//别忘了把背景设为null,避免onDraw刷新背景时候出现used a recycled bitmap错误
bd.setCallback(null);
bd.getBitmap().recycle();
2. 使用字节流,突破Android heap size的限制
从中不难发现,bitmap的存放位置根据Android版本的不同真的有所不同。好了,下面就是找出怎么把图片存放到native heap里就行了,BitmapFactory里就那么几个decode方法,很容易找到BitmapFactory .decodeStream就可以解决。下面贴一下代码:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.ARGB_8888;
options.inPurgeable = true;// 允许可清除
options.inInputShareable = true;// 以上options的两个属性必须联合使用才会有效果
String sname = String.format( “xxx.png”, sTowerStyle, j, sDirction, i);
InputStream is = am.open(sname);
arrBmp[ iBmpIndex] = BitmapFactory .decodeStream(is, null, options);
ok搞定收工。
尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,
因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。
因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,
decodeStream最大的秘密在于其直接调用JNInativeDecodeAsset()来完成decode,
无需再使用java层的createBitmap,从而节省了java层的空间。
如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常
另外,decodeStream直接拿的图片来读取字节码了, 不会根据机器的各种分辨率来自动适应,
使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,
否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。
关于JAVA文件上传的奇怪OOM问题
可能是jvm运行时内存不足吧,你试下
java -Xms512m -Xmx512m -XX:MaxPermSize=128m -cp lib/bootstart.jar; TestJava
Xmx 用来设置你的应用程序能够使用的最大内存数(看好,致使你的应用程序,不是整个jvm),如果你的程序要花很大内存的话,那就需要修改缺省的设置,比如配置tomcat的时候,如果流量啊程序啊都很大的话就需要加大这个值了,不过有一点是要记住的,不要大得超过你的机器的内存,那样你的机器会受不了的,到时候就死翘翘了。
Xms 用它来设置程序初始化的时候内存栈的大小,增加这个值的话你的程序的启动性能会得到提高。不过同样有前面的限制,以及受到xmx的限制。
java oom 进程为什么退出
防止重要的系统进程触发(OOM)机制而被杀死:可以设置参数/proc/PID/oom_adj为-17,可临时关闭linux内核的OOM机制。内核会通过特定的算法给每个进程计算一个分数来决定杀哪个进程,每个进程的oom分数可以/proc/PID/oom_score中找到。我们运维过程中保护的一般是sshd和一些管理agent。
保护某个进程不被内核杀掉可以这样操作:
# echo -17 /proc/$PID/oom_adj
如何防止sshd被杀,可以这样操作:
# pgrep -f "/usr/sbin/sshd" | while read PID;do echo -17 /proc/$PID/oom_adj;done
可以在计划任务里加入这样一条定时任务,就更安全了:
#/etc/cron.d/oom_disable
*/1**** root pgrep -f "/usr/sbin/sshd" | while read PID;do echo -17 /proc/$PID/oom_adj;done
为了避免重启失效,可以写入/etc/rc.d/rc.local
echo -17 /proc/$(pidof sshd)/oom_adj
至于为什么用-17而不用其他数值(默认值为0),这个是由linux内核定义的,查看内核源码可知:
以linux-3.3.6版本的kernel源码为例,路径为linux-3.6.6/include/linux/oom.h,阅读内核源码可知oom_adj的可调值为15到-16,其中15最大-16最小,-17为禁止使用OOM。oom_score为2的n次方计算出来的,其中n就是进程的oom_adj值,所以oom_score的分数越高就越会被内核优先杀掉。
当然还可以通过修改内核参数禁止OOM机制
# sysctl -w vm.panic_on_oom=1
vm.panic_on_oom = 1 //1表示关闭,默认为0表示开启OOM
# sysctl -p
java中的oom的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java中的oom是什么意思、java中的oom的信息别忘了在本站进行查找喔。
发布于:2022-12-24,除非注明,否则均为
原创文章,转载请注明出处。