小与生存期必须是确定的无灵活 性。
java 堆分为三个区: New 、 Old 和 Permanent
GC 有两个线程:
新创建的对象被分配到 New 区,当该区被填满时会被 GC 辅助线程移到 Old 区,当 Old 区也填满了会触发 GC 主线程遍历堆内存里的所有对象。 Old 区的大小等于 Xmx 减去 -Xmn
java栈存放
栈调整:参数有 +UseDefaultStackSize -Xss256K,表示每个线程可申请 256k的栈空间
每个线程都有他自己的 Stack
三、 JVM如何设置虚拟内存
提示:在 JVM中如果 98%的时间是用于 GC且可用的 Heap size 不足 2%的时候将抛出此异常信息。
提示: Heap Size 最大不要超过可用物理内存的 80%,一般的要将 -Xms和 -Xmx选项设置为相同,而 -Xmn为 1/4的 -Xmx值。
提示: JVM初始分配的内存由 -Xms指定,默认是物理内存的 1/64; JVM最大分配的内存由 -Xmx指定,默认是物理内存的 1/4。
默认空余堆内存小于 40%时, JVM就会增大堆直到 -Xmx的最大限制;空余堆内存大于 70%时, JVM会减少堆直到 -Xms的最小限制。因此服务器一般设置 -Xms、 -Xmx相等以避免在每次 GC 后调整堆的大小。
提示:假设物理内存无限大的话, JVM内存的最大值跟操作系统有很大的关系。
简单的说就 32位处理器虽然可控内存空间有 4GB,但是具体的操作系统会给一个限制,
这个限制一般是 2GB-3GB(一般来说 Windows
系统下为 1.5G-2G, Linux系统下为 2G-3G), 而
64bit以上的处理器就不会有限制了
提示:注意:如果 Xms超过了 Xmx值,或者堆最大值和非堆最大值的总和超过了物理内 存或者操作系统的最大限制都会引起服务器启动不起来。
提示:设置 NewSize、 MaxNewSize相等, “new”的大小最好不要大于 “old”的一半,原因是 old区如果不够大会频繁的触发 “主 ” GC ,大大降低了性能
JVM使用 -XX:PermSize设置非堆内存初始值,默认是物理内存的 1/64;
由 XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的 1/4。
解决方法:手动设置 Heap size
修改 TOMCAT_HOME/bin/catalina.bat
在“ echo “Using CATALINA_BASE: $CATALINA_BASE””上面加入以下行:
JAVA_OPTS=”-server -Xms800m -Xmx800m -XX:MaxNewSize=256m”
四、性能检查工具使用
定位内存泄漏:
JProfiler 工具主要用于检查和跟踪系统(限于 Java 开发的)的性能。 JProfiler 可以通过时时的监控系统的内存使用情况,随时监视垃圾回收,线程运行状况等手段,从而很好的监视 JVM 运行情况及其性能。
1. 应用服务器内存长期不合理占用,内存经常处于高位占用,很难回收到低位;
2. 应用服务器极为不稳定,几乎每两天重新启动一次,有时甚至每天重新启动一次;
3. 应用服务器经常做 Full GC(Garbage Collection),而且时间很长,大约需要 30-40秒,应用服务器在做 Full GC的时候是不响应客户的交易请求的,非常影响系统性能。
因为开发环境和产品环境会有不同,导致该问题发生有时会在产品环境中发生, 通常可以使用工具跟踪系统的内存使用情况,在有些个别情况下或许某个时刻确实 是使用了大量内存导致 out of memory,这时应继续跟踪看接下来是否会有下降,
如果一直居高不下这肯定就因为程序的原因导致内存泄漏。
五、不健壮代码的特征及解决办法
1 、尽早释放无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动设置为 null ,暗示垃圾收集器来收集该对象,防止发生内存泄露。
对于仍然有指针指向的实例, jvm 就不会回收该资源 , 因为垃圾回收会将值为 null 的对象作为垃圾,提高 GC 回收机制效率;
2 、我们的程序里不可避免大量使用字符串处理,避免使用 String ,应大量使用 StringBuffer ,每一个 String 对象都得独立占用内存一块区域;
String str = “aaa”;
String str2 = “bbb”;
String str3 = str + str2;// 假如执行此次之后 str ,str