-Xms128m JVM初始分配的堆内存
-Xmx512m JVM最大允许分配的堆内存,按需分配
-XX:PermSize=64M JVM初始分配的非堆内存
-XX:MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配
1、程序计数器
程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看
做是当前线程所执行的字节码的行号指示器。
2、Java 虚拟机栈
与程序计数器一样,Java 虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,
它的生命周期与线程相同。
3、本地方法栈
本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其
区别不过是虚拟机栈为虚拟机执行Java 方法(也就是字节码)服务,而本地方法栈则
是为虚拟机使用到的Native 方法服务。
Java 堆中还可以细分为:新生代和老年代;
再细致一点的有Eden 空间、From Survivor 空间、To Survivor 空间等。如果从内存分配
的角度看,线程共享的Java 堆中可能划分出多个线程私有的分配缓冲区(Thread Local
Allocation Buffer,TLAB)。不过,无论如何划分,都与存放内容无关,无论哪个区域,
存储的都仍然是对象实例,进一步划分的目的是为了更好地回收内存,或者更快地分配
内存。
虽然Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-
Heap(非堆),目的应该是与Java 堆区分开来。
对于习惯在HotSpot 虚拟机上开发和部署程序的开发者来说,很多人愿意把方法区称为“永久代”(Permanent Generation),本质上两者并不等价。
6、运行时常量池
运行时常量池(Runtime Constant Pool)是方法区的一部分。
6、直接内存
直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java
虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致
OutOfMemoryError 异常出现,
jdk1.7常用的调试命令
1.jps
查看java进程号,例如:
D:\jdk7\bin>jps
9616 Jps
4136 org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar
上例的 4136 就是java进程号(eclispe的)
2.jstat -gc 进程号
查看某进程gc情况,例如:
D:\jdk7\bin>jstat -gc 4136
S0C S1C S0U S1U EC EU OC OU PC PU
YGC YGCT FGC FGCT GCT
44544.0 44544.0 0.0 44540.0 268800.0 139260.2 715776.0 105657.3 101376.0
101048.6 3 0.310 0 0.000 0.310
3.jstat -gcutil 进程号
查看某进程gc情况 ,百分比情况:
D:\jdk7\bin>jstat -gcutil 4136
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 99.99 51.81 14.76 99.68 3 0.310 0 0.000 0.310
4.jinfo 进程号
查看某进程的java运行期参数
jinfo -flag CMSInitiatingOccupancyFraction
查看指定参数的值
5.jmap -dump:format=b,file=eclipse.bin 进程号
dump指定的进程到文件。
6. jhat 文件名
分析dump文件,生产报告,默认访问地址http://localhost:7000/
7.jvisualvm.exe可视化的java内存分析工具。新一代分析工具功能强大。
增加了gc插件后的界面,增加插件的方法 工具-〉插件-〉可用插件-〉Visual GC
但是,注意Visual VM分析工具本身也是挺消耗系统性能的。
经验:
1.使用Spring 和hibatnatie等框架,容易引起永久代”(Permanent Generation)占满,动态代理类的原因?
2.使用Apache NIO的类包,容易引发直接内存(Direct Memory)占满。
3.JVM内存并非越大越好,32位JVM有时候比64位JVM运行速度更快。如果,要消耗机器硬件性能,不妨多启动几个Tomcat,分别用不同端口。32JVM的内存管理不能超过2GB,64位JVM才可以超过4GB。
(理论上来说32位的JVM有4G的堆大小限制。但是因为各种条件限制比如交换区,内核地址空间使用,内存碎片,虚拟管理机的管理开销,实际上可用的堆的大小远远比理论上的4G要少。
在32位windows的机器上,堆最大可以达到1.4G至1.6G。
在32位solaris的机器上,堆最大可以达到2G
而在64位的操作系统上,32位的JVM,堆大小可以达到4G)
4.在linux环境下 ,kill -3 pid 的方式发送一个SIGQUIT信号给Java应用之后,通常会有当前的Thread Dump输出。(吓唬JVM输出Dump),但是,服务器环境的 dump动 不动 就是上G的文件,即使Dump出来也很难分析。
5.一种土办法是 卸载可能产生问题的模块,按个去试试是否会内存溢出。这跟修电脑的原理有点类似。