1、StackOverFlowError:栈溢出
1)实例:下面代码报java.lang.StackOverError
public class StackeOverFlowTest{
public static void main(String []args){
new StackOverStackTest().testStackOver();
}
public void testStackOver(){
testStackOver();
}
}
2、其他的一些内存溢出
1)unable to create new native thread :栈本身是占用空间的,存放在Native Memory中,通过-Xss设置私有栈空间的大小,也就是对一个线程来将他的私有空间的最大的限制,若超出了这个大小,会报上述的错误
2)request{}byte for{}out of swap:基本是地址空间不够用,报该错误
3)IOEception:Too many open files:是由于有太多没有关闭的套接字导致的问题
3、常见的java工具
1)jps:jps是最简单的一种命令工具,仅仅过滤java本身的进程以及运行的引导类,jps是基于Java实现的,有点类似于下面的代码实现逻辑,代码中拿到虚拟机描述对象后,可以用过VirtualMachine.attach(des)来链接对应的服务器
public class JpsTest{
public static void main(string [] args){
List<VirtualMachineDescriptor> machineDescriptors = new
VirtualMachine.list();
for(VirtualMachineDescriptor des : machineDescriptors){
System.out.prinln(des.id() + des.displayName());
}
}
}
2)jstat:用于快速的定位问题的一种方式,使用它可以方便看到JVM中每个区域的情况,根据不同的参数,看到每个区域的使用情况和比例,例如:jstat -gcutil<pid> 1000 2 ,其中<pid>代表进程号,1000代表每1000ms采集一次数据,最后一个参数2代表总共采集俩次数据
S0 | S1 | E | O | P | YGC | YGCT | FGC | FGCT | GCT |
0.00 | 31.67 | 3.12 | 26.03 | 74.81 | 287 | 2.315 | 0 | 0.000 | 2.315 |
其中:S0、S1:俩个Survitor,E:Eden,O:Old,P:Perm,数字代表占的百分比,YGC、FGC:Minor GC、FULL GC的次数,YGCT、FGCT:俩种GC所用的总时间,GCT代表所有GC的时间
-gcutil可以换成-gccause、-gc、-gcnew、-gcnewcapacity、-calass、-compiler、-printcompilation等,查看不同的数据
3)jmap:使用dump内存时,系统会呗暂停,如果dump的一个超大的JVM内存的文件,普通的机器无法跑起来
a)jmap -heap<pid> :用于查看,某些OS上不支持
b)jmap -histo<pid>:输出活着的对象数以及大小,可以将其重定向到一个文件中
c)jmap -dump:format=b,file=heap.bin<pid>:导出JVM内存信息并形成二进制文件,都使用MAT工具分析
4)jstack:主要输出线程信息,例如:线程名称、地址、状态等
5)jinfo:查看某些运行时参数或者去做一些修改
6)JConsule:图形化工具,在具有图形化的OS命令行输入“jconsole”或者到JDK的bin目录下找到JSconsole五年级,双击运行
7)设置服务器用户名及密码:
a)Linux下在JAVA_HOME/jre/lib/management/目录下有个文件“jmxremote.password.template”(Windows下改为%JAVA_HOME%),复制一个,将template后缀删掉,将文件内容打开,去掉注释,该俩行是java默认额jmx用户及密码,同一目录下“jmxremote.access”文件,存在上诉的2个用户,可以在该文件里增加自己的用户
b)在启动JVM进程的启动参数上新增以下内容
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9000 -Dcom.sun.management.jmxremote=false |
c)客户端其动感JConsole,输入用户名和密码以及远程主机ip:port
d)修改“jmxremote.password”文件为 只读:Linux下使用root账号,修改完用户密码后将jmxremote.password文件属性设置为000也就是执行该命令:chmod 000 jmxremote.password,Windows下可以将jmxremote.password属性—》编辑—》安全 —》只读。
8)Visual VM :可以集成非常多工具的平台,在JDK的目录下运行“visualvm.exe”,安装插件时只需要关注Tools —》“Available Plugins”、“Installed”,
a)设置远程监控:编辑文件,例如文件名称为“visualvm.remote.policy”,可以放到任意的目录下,例如放在“/ux/security/“,文件内容如下:
grant codebase “file:${java.home}/../lib/tools.jar”{ permission java.security.AllPermission; } |
b)运行jstatd工具,如下命令:
Jstatd -J-Djava.policy=/ux/security/vosualvm.romote.policy -p 9000 |
c)若运行正常,则在对应的服务器上开启了9000端口,可以接受来自远程的Visual VM 工具访问
9)MAT:它是java的内存分析工具,分析的是JVM内存的dump文件,程序本身也是通过java写的
10)BTrace:程序出现问题时,可以将该问题类中的某个方法或写入过的数据的时候,将调用这个类的相应方法的“调用栈路径”打印出来。
a)内部实现:使用字节码增强技术来实现代码的跟踪,基于java的Attach API
11)HSDB:类似于Visual VM 集成了很多工具,只是它在命令行下使用
a)启动方式:java -classpath:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB,如果是windows,将$JAVA_HOME修改成%JAVA_HOME%
4、总结:
1)程序可控时,申请根小的内存可以做完的事情,不要申请多余的内存,但是要把握一个“度”
2)处理大数据量时,要分段来处理
3)处理大批量的肖I/O操作,尝试哟过批处理方式
4)局部代码块中已经申请了许多占用空间的对象,这些对象在其“作用域”内的后续代码块中还要执行很长时间,并且这块内存在后面不会在使用了,尝试着将一些大的对象设置为null
5)程序中的对象尽量缩小它的作用域
6)当应用中存在某些内存经常被用到,不会改变,但加载到内存代价比较大,在进程启动将其填充号,避免与业务代码中内存使用抢占Survivor空间
7)当某些数据中有Cache时,尽量使用它
8)当遇到一些反复叠加的操作,例如字符串的叠加,尝试使用一个外部引用变量或者是对象来操作,减少叠加过过程中产生的碎片