java 什么时候会oom(什么情况下OOM会终止java进程)
大家好,java 什么时候会oom相信很多的网友都不是很明白,包括什么情况下OOM会终止java进程也是一样,不过没有关系,接下来就来为大家分享关于java 什么时候会oom和什么情况下OOM会终止java进程的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我们开始吧!
什么情况下OOM会终止java进程
防止重要的系统进程触发(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垃圾回收:GC在什么时候对什么做了什么
GC在什么时候对什么做了什么?
要回答这个问题,先了解下GC的发展史、jvm运行时数据区的划分、jvm内存分配策略、jvm垃圾收集算法等知识。
先说下jvm运行时数据的划分,粗暴的分可以分为堆区(Heap)和栈区(Stack),但jvm的分法实际上比这复杂得多,大概分为下面几块:
1、程序计数器(Program Conuter Register)
程序计数器是一块较小的内存空间,它是当前线程执行字节码的行号指示器,字节码解释工作器就是通过改变这个计数器的值来选取下一条需要执行的指令。它是线程私有的内存,也是唯一一个没有OOM异常的区域。
2、Java虚拟机栈区(Java Virtual Machine Stacks)
也就是通常所说的栈区,它描述的是Java方法执行的内存模型,每个方法被执行的时候都创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等。每个方法被调用到完成,相当于一个栈帧在虚拟机栈中从入栈到出栈的过程。此区域也是线程私有的内存,可能抛出两种异常:如果线程请求的栈深度大于虚拟机允许的深度将抛出StackOverflowError;如果虚拟机栈可以动态的扩展,扩展到无法动态的申请到足够的内存时会抛出OOM异常。
3、本地方法栈(Native Method Stacks)
本地方法栈与虚拟机栈发挥的作用非常相似,区别就是虚拟机栈为虚拟机执行Java方法,本地方法栈则是为虚拟机使用到的Native方法服务。
4、堆区(Heap)
所有对象实例和数组都在堆区上分配,堆区是GC主要管理的区域。堆区还可以细分为新生代、老年代,新生代还分为一个Eden区和两个Survivor区。此块内存为所有线程共享区域,当堆中没有足够内存完成实例分配时会抛出OOM异常。
5、方法区(Method Area)
方法区也是所有线程共享区,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。GC在这个区域很少出现,这个区域内存回收的目标主要是对常量池的回收和类型的卸载,回收的内存比较少,所以也有称这个区域为永久代(Permanent Generation)的。当方法区无法满足内存分配时抛出OOM异常。
6、运行时常量池(Runtime Constant Pool)
运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。
垃圾收集(Garbage Collection)并不是Java独有的,最早是出现在Lisp语言中,它做的事就是自动管理内存,也就是下面三个问题:
1、什么时候回收
2、哪些内存需要回收
3、如何回收
1、什么时候回收?
上面说到GC经常发生的区域是堆区,堆区还可以细分为新生代、老年代,新生代还分为一个Eden区和两个Survivor区。
1.1对象优先在Eden中分配,当Eden中没有足够空间时,虚拟机将发生一次Minor GC,因为Java大多数对象都是朝生夕灭,所以Minor GC非常频繁,而且速度也很快;
1.2 Full GC,发生在老年代的GC,当老年代没有足够的空间时即发生Full GC,发生Full GC一般都会有一次Minor GC。大对象直接进入老年代,如很长的字符串数组,虚拟机提供一个-XX:PretenureSizeThreadhold参数,令大于这个参数值的对象直接在老年代中分配,避免在Eden区和两个Survivor区发生大量的内存拷贝;
1.3发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则进行一次Full GC,如果小于,则查看HandlePromotionFailure设置是否允许担保失败,如果允许,那只会进行一次Minor GC,如果不允许,则改为进行一次Full GC。
2、哪些内存需要回收
jvm对不可用的对象进行回收,哪些对象是可用的,哪些是不可用的?Java并不是采用引用计数算法来判定对象是否可用,而是采用根搜索算法(GC Root Tracing),当一个对象到GC Roots没有任何引用相连接,用图论的来说就是从GC Roots到这个对象不可达,则证明此对象是不可用的,说明此对象可以被GC。对于这些不可达对象,也不是一下子就被GC,而是至少要经历两次标记过程:如果对象在进行根搜索算法后发现没有与GC Roots相连接的引用链,那它将会第一次标记并且进行一次筛选,筛选条件是此对象有没有必要执行finalize()方法,当对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用执行过一次,这两种情况都被视为没有必要执行finalize()方法,对于没有必要执行finalize()方法的将会被GC,对于有必要有必要执行的,对象在finalize()方法中可能会自救,也就是重新与引用链上的任何一个对象建立关联即可。
3、如何回收
选择不同的垃圾收集器,所使用的收集算法也不同。
在新生代中,每次垃圾收集都发现有大批对象死去,只有少量存活,则使用复制算法,新生代内存被分为一个较大的Eden区和两个较小的Survivor区,每次只使用Eden区和一个Survivor区,当回收时将Eden区和Survivor还存活着的对象一次性的拷贝到另一个Survivor区上,最后清理掉Eden区和刚才使用过的Survivor区,Eden和Survivor的默认比例是8:1,可以使用-XX:SurvivorRatio来设置该比例。
而老年代中对象存活率高,没有额外的空间对它进行分配担保,必须使用“标记-清理”或“标记-整理”算法。
java 读20M的excel,怎么做才不抛oom
一般都是用jacob的,这里不能发地址,自己搜一下,要下1.9的版本
1、我们解开下载的jacob_1.9.zip,在文件夹中找到jacob.dll和jacob.jar两个文件
2、将压缩包解压后,Jacob.jar添加到Libraries中;
3、将Jacob.dll放至“WINDOWS\SYSTEM32”下面。
需要注意的是:
【使用IDE启动Web服务器时,系统读取不到Jacob.dll,例如用MyEclipse启动Tomcat,就需要将dll文件copy到MyEclipse安装目录的“jre\bin”下面。
一般系统没有加载到Jacob.dll文件时,报错信息为:“java.lang.UnsatisfiedLinkError: no jacob in java.library.path”】
使用Jacob转换Word,Excel为HTML
JAVA代码:
Java代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class TransformFiletoHtml
{
int WORD_HTML= 8;
int WORD_TXT= 7;
int EXCEL_HTML= 44;
/**
* WORD转HTML
*@param docfile WORD文件全路径
*@param htmlfile转换后HTML存放路径
*/
public void wordToHtml(String docfile, String htmlfile)
{
ActiveXComponent app= new ActiveXComponent("Word.Application");//启动word
try
{
app.setProperty("Visible", new Variant(false));
Dispatch docs= app.getProperty("Documents").toDispatch();
Dispatch doc= Dispatch.invoke(docs,"Open",Dispatch.Method,new Object[], new int[1]).toDispatch();
Dispatch.invoke(doc,"SaveAs", Dispatch.Method, new Object[], new int[1]);
Variant f= new Variant(false);
Dispatch.call(doc,"Close", f);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
app.invoke("Quit", new Variant[]{});
}
}
/**
* EXCEL转HTML
*@param xlsfile EXCEL文件全路径
*@param htmlfile转换后HTML存放路径
*/
public void excelToHtml(String xlsfile, String htmlfile)
{
ActiveXComponent app= new ActiveXComponent("Excel.Application");//启动excel
try
{
app.setProperty("Visible", new Variant(false));
Dispatch excels= app.getProperty("Workbooks").toDispatch();
Dispatch excel= Dispatch.invoke(excels,"Open",Dispatch.Method,new Object[], new int[1]).toDispatch();
Dispatch.invoke(excel,"SaveAs", Dispatch.Method, new Object[], new int[1]);
Variant f= new Variant(false);
Dispatch.call(excel,"Close", f);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
app.invoke("Quit", new Variant[]{});
}
}
/**
*/删除指定文件夹
*@param folderPath文件夹全路径
*@param htmlfile转换后HTML存放路径
*/
public void delFolder(String folderPath)
{
try
{
delAllFile(folderPath);//删除完里面所有内容
String filePath= folderPath;
filePath= filePath.toString();
java.io.File myFilePath= new java.io.File(filePath);
myFilePath.delete();//删除空文件夹
} catch(Exception e)
}
/**
*/删除指定文件夹下所有文件
*@param path文件全路径
*/
public boolean delAllFile(String path)
{
boolean flag= false;
File file= new File(path);
if(!file.exists())
{
return flag;
}
if(!file.isDirectory())
{
return flag;
}
String[] tempList= file.list();
File temp= null;
for(int i= 0; i< tempList.length; i++)
{
if(path.endsWith(File.separator))
{
temp= new File(path+ tempList[i]);
}
else
{
temp= new File(path+ File.separator+ tempList[i]);
}
if(temp.isFile())
{
temp.delete();
}
if(temp.isDirectory())
{
delAllFile(path+"/"+ tempList[i]);//先删除文件夹里面的文件
delFolder(path+"/"+ tempList[i]);//再删除空文件夹
flag= true;
}
}
return flag;
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class TransformFiletoHtml
{
int WORD_HTML= 8;
int WORD_TXT= 7;
int EXCEL_HTML= 44;
/**
* WORD转HTML
*@param docfile WORD文件全路径
*@param htmlfile转换后HTML存放路径
*/
public void wordToHtml(String docfile, String htmlfile)
{
ActiveXComponent app= new ActiveXComponent("Word.Application");//启动word
try
{
app.setProperty("Visible", new Variant(false));
Dispatch docs= app.getProperty("Documents").toDispatch();
Dispatch doc= Dispatch.invoke(docs,"Open",Dispatch.Method,new Object[], new int[1]).toDispatch();
Dispatch.invoke(doc,"SaveAs", Dispatch.Method, new Object[], new int[1]);
Variant f= new Variant(false);
Dispatch.call(doc,"Close", f);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
app.invoke("Quit", new Variant[]{});
}
}
/**
* EXCEL转HTML
*@param xlsfile EXCEL文件全路径
*@param htmlfile转换后HTML存放路径
*/
public void excelToHtml(String xlsfile, String htmlfile)
{
ActiveXComponent app= new ActiveXComponent("Excel.Application");//启动excel
try
{
app.setProperty("Visible", new Variant(false));
Dispatch excels= app.getProperty("Workbooks").toDispatch();
Dispatch excel= Dispatch.invoke(excels,"Open",Dispatch.Method,new Object[], new int[1]).toDispatch();
Dispatch.invoke(excel,"SaveAs", Dispatch.Method, new Object[], new int[1]);
Variant f= new Variant(false);
Dispatch.call(excel,"Close", f);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
app.invoke("Quit", new Variant[]{});
}
}
/**
*/删除指定文件夹
*@param folderPath文件夹全路径
*@param htmlfile转换后HTML存放路径
*/
public void delFolder(String folderPath)
{
try
{
delAllFile(folderPath);//删除完里面所有内容
String filePath= folderPath;
filePath= filePath.toString();
java.io.File myFilePath= new java.io.File(filePath);
myFilePath.delete();//删除空文件夹
} catch(Exception e)
}
/**
*/删除指定文件夹下所有文件
*@param path文件全路径
*/
public boolean delAllFile(String path)
{
boolean flag= false;
File file= new File(path);
if(!file.exists())
{
return flag;
}
if(!file.isDirectory())
{
return flag;
}
String[] tempList= file.list();
File temp= null;
for(int i= 0; i< tempList.length; i++)
{
if(path.endsWith(File.separator))
{
temp= new File(path+ tempList[i]);
}
else
{
temp= new File(path+ File.separator+ tempList[i]);
}
if(temp.isFile())
{
temp.delete();
}
if(temp.isDirectory())
{
delAllFile(path+"/"+ tempList[i]);//先删除文件夹里面的文件
delFolder(path+"/"+ tempList[i]);//再删除空文件夹
flag= true;
}
}
return flag;
}
}调用JAVA代码:
Java代码
public class Test1{
public static void main(String[] args){
// TODO Auto-generated method stub
TransformFiletoHtml trans= new TransformFiletoHtml();
trans.wordToHtml("D:\\sinye.doc","D:\\sinye.html");
}
}
public class Test1{
public static void main(String[] args){
// TODO Auto-generated method stub
TransformFiletoHtml trans= new TransformFiletoHtml();
trans.wordToHtml("D:\\sinye.doc","D:\\sinye.html");
}
}只写了一个测试word转html的,excel转html的同理,在TransformFiletoHtml类中,写了两个方法,一个是删除文件夹的方法(delFolder()),一个是删除文件夹下所有文件的方法(delAllFile())。
关于java 什么时候会oom的内容到此结束,希望对大家有所帮助。