[转载]Java启动参数与内存调优一些学习笔记

.参数的含义
-Xms128m JVM初始分配的堆内存
-Xmx512m JVM最大允许分配的堆内存,按需分配
-XX:PermSize=64M JVM初始分配的非堆内存
-XX:MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配

JVM内存模型

1、程序计数器
程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看

做是当前线程所执行的字节码的行号指示器。

2、Java 虚拟机栈

与程序计数器一样,Java 虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,

它的生命周期与线程相同。

Java 内存区分为堆内存(Heap)和栈内存(Stack),这种分法比较粗糙,Java 内存区域的划分实际上远比这复杂。

3、本地方法栈
本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其

区别不过是虚拟机栈为虚拟机执行Java 方法(也就是字节码)服务,而本地方法栈则

是为虚拟机使用到的Native 方法服务。

扫描二维码关注公众号,回复: 5383770 查看本文章

4、Java 堆
Java 堆中还可以细分为:新生代和老年代;

再细致一点的有Eden 空间、From Survivor 空间、To Survivor 空间等。如果从内存分配

的角度看,线程共享的Java 堆中可能划分出多个线程私有的分配缓冲区(Thread Local

Allocation Buffer,TLAB)。不过,无论如何划分,都与存放内容无关,无论哪个区域,
存储的都仍然是对象实例,进一步划分的目的是为了更好地回收内存,或者更快地分配

内存。

5、方法区
虽然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指定的进程到文件。

  1. 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.一种土办法是 卸载可能产生问题的模块,按个去试试是否会内存溢出。这跟修电脑的原理有点类似。

猜你喜欢

转载自blog.csdn.net/weixin_37791303/article/details/87818581