`
lengyu
  • 浏览: 2585 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

jvm runtime contant pool String 占用测试

    博客分类:
  • jvm
阅读更多

最近公司测试环境Cassandra的一次PermGen Space,好久没排查此类问题了,对JVM也有点陌生,借此机会重新学习学习,经过一段时间的不断尝试,终于基本定位问题所在,PermGen OOM 是因为Casandra 在运行过程中不断的往PermGen里面放入String常量导致OOM,但没找到Cassandra在什么情况下会不断的产生新的String 常量,还要继续跟进。

排查过程如下: 

 

       好久没真正排查OOM问题了,一开始也没什么办法,只好重新启动Cassandra ,过一段时间又继续OOM,一直感觉很诡异,之前运行那么久都没有问题,怎么现在老是OOM,查看OOM日志,也没什么明确信息,然后拿着OOM时的java_pidXXX.hprof文件,通过Eclipse 的MemoryAanlyzerTool工具分析,看了半天,也没看出来什么明显问题,后来无意中发现jmap这个命令(其实之前也用过,好久没用了都忘得差不多了,看来久不久得练练)可以直接查看当前heap使用情况,直接jmap -heap pid,发现我们Cassandra实例内存默认配置如下:

Heap Configuration:

   MinHeapFreeRatio = 40

   MaxHeapFreeRatio = 70

   MaxHeapSize      = 2147483648 (2048.0MB)

   NewSize          = 419430400 (400.0MB)

   MaxNewSize       = 419430400 (400.0MB)

   OldSize          = 5439488 (5.1875MB)

   NewRatio         = 2

   SurvivorRatio    = 8

   PermSize         = 21757952 (20.75MB)

   MaxPermSize      = 85983232 (82.0MB)

 

PernGen Size 的值使用JVM默认值,配置中没有具体指定,而我们的Cassandra OOM以后又启动起来,Perm Generation 已经使用了81M,接近100%的使用率,怪不得运行一段时间以后又继续OOM,只好手动设置Cassandra MaxPermSize=256M,重新启动,感觉这样也没查出具体问题,继续查看permstat,命令

jmap -permstat pid

发现218566 intern Strings occupying 66681200 bytes,终于确定问题所在,原来里面保存了65M的String常量

现在基本确定OOM的原因了,但还是没搞清楚Cassandra是如何在运行过程中把String常量放入PermGen,还需继续努力。

 

下面是测试String的不同使用方法对JVM内存的使用情况:

 

环境:

java version "1.6.0_51"

jvm: Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01-457, mixed mode)

 

程序伪代码1:

i=0

if(i<100000)

      i++;

String.valueOf(i).intern()

 

结论:

1、String 对象会在新生代创建并占用内存

2、String 的值会被放入永久代中并占用内存

2、当新生代GC时,不会把String对象指向的String字符串转入老年代中,这些字符串已经被放入永久代,只会把String对象其他信息(具体还不能确定是什么信息)放入老年代

 

占用内存相对较少,但String字符串存放在永久代,下面是YGC=4的时候,JVM使用情况

S0C     S1C     S0U   S1U      EC         EU          OC            OU          PC       PU      YGC  YGCT  FGC  FGCT     GCT

2112.0 2112.0  9.8    0.0   17024.0   571.0    63872.0     7337.4   11264.0 11120.7      4    0.023   0      0.000    0.023

 

程序伪代码2:

i=0

if(i<100000)

      i++;

String.valueOf(i) 或者new String(i+"")或者 i+""

 

结论:

1、String 对象会在新生代创建并占用内存

2、String 的值不会被放入永久代中并占用内存

2、当新生代GC时,会把String对象指向的String字符串和String对象其他信息都放入老年代

 

new String(i+"") 占用内存相对较少,下面是YGC=4的时候,JVM使用情况

  S0C     S1C     S0U   S1U      EC         EU          OC            OU          PC       PU      YGC  YGCT  FGC  FGCT     GCT

2112.0 2112.0 2112.0  0.0   17024.0   5835.4   63872.0    28361.7   5120.0 4952.8      4    0.064   0      0.000    0.064

 

i+"“ 与 new String(i+"") 占用内存差不多,下面是YGC=4的时候,JVM使用情况

S0C     S1C     S0U   S1U      EC         EU          OC            OU          PC       PU      YGC  YGCT  FGC  FGCT     GCT

2112.0 2112.0 2112.0  0.0   17024.0   965.2    63872.0    28373.7   5120.0 4952.5      4    0.081   0      0.000    0.081

 

String.valueOf(i) 占用内存相对较多,下面是YGC=4的时候,JVM使用情况

 S0C     S1C     S0U   S1U      EC         EU          OC            OU          PC       PU      YGC  YGCT  FGC  FGCT     GCT

2112.0 2112.0 2112.0  0.0   17024.0   571.0    92956.0    55772.8   8252.0 4949.8      4    0.129  96      0.468    0.598

 

 

分享到:
评论

相关推荐

    java JVM Runtime Data Area and Instruction Set

    java JVM Runtime Data Area and Instruction Set

    深入理解JVM实战篇-String类1

    《深入理解JVM实战篇-String类》 在Java编程中,String类是使用最频繁的类之一,它涉及到许多底层机制,特别是与JVM(Java虚拟机)的交互。本文将探讨String类的一些关键特性,包括字面量与运行时常量池、String的...

    有关String的测试程序包含string内部一些函数

    本测试程序旨在深入理解和探索`String`类的一些核心功能和内部机制。以下是一些关于`String`类的关键知识点: 1. **不可变性**:`String`对象在创建后就不能更改。这意味着一旦创建了`String`实例,它的值就固定了...

    java 测试jvm工具可执行加入

    java 测试jvm工具可执行加入java 测试jvm工具可执行加入java 测试jvm工具可执行加入java 测试jvm工具可执行加入java 测试jvm工具可执行加入java 测试jvm工具可执行加入java 测试jvm工具可执行加入java 测试jvm工具可...

    JVM内存分配及String常用方法解析

    "JVM内存分配及String常用方法解析" 通过对JVM内存分配和String常用方法的解析,我们可以了解到JVM的内存模型和String类的使用方法。 一、JVM内存分配 JVM将内存分为多个不同的区域,每个区域都有其特定的用途和...

    JVM监控实例数 windows监控 线程测试 单例模式下测试JVM实例是否一个

    本文将探讨如何在Windows环境下通过简单的命令行工具来监控JVM实例的数量,以及如何进行线程测试,特别是在单例模式下的JVM实例验证。 首先,了解如何监控JVM实例数量。在Windows操作系统中,我们可以使用`jps`命令...

    jvm 内存分析文档

    - **运行时常量池(Runtime Constant Pool)**:存储类文件的常量,包括字符串字面量和符号引用。在Java 8中,运行时常量池也被移到了堆中。 ### 2. JVM Heap 内存结构 堆内存是Java对象的主要存储区域,分为...

    测定JVM中对象占用内存—SizeOf

    原项目下载地址:...使用说明: 1、将SizeOf.jar放到Eclipse工程路径下,添加到classpath中; 2、运行前添加VM参数:-javaagent:lib/SizeOf.jar 运行即可(将jar放在lib路径下)。

    JVM虚拟机复习宝典

    - **Runtime Constant Pool(运行时常量池)**:运行时常量池是方法区的一部分,它包含了Class文件中的常量池内容。这些内容会在类加载后进入方法区的运行时常量池中。此外,运行时常量池还支持动态性,即允许在运行...

    64位 java runtime 1.8.0.zip

    Java Runtime Environment(JRE)是Java程序运行所需的基础组件,它是Oracle公司提供的Java平台标准版(Java SE)的一部分。在本例中,我们讨论的是64位版本的JRE 1.8.0,适用于Windows操作系统。这个版本的JRE包含...

    推荐一些JVM原理,JVM调优,JVM内存模型,JAVA并发 电子书1

    标题中提到了JVM原理、JVM调优、JVM内存模型和JAVA并发,这些都是Java虚拟机(JVM)相关的核心概念。JVM是运行Java字节码的虚拟计算机,为Java提供了一个跨平台的环境,确保Java程序可以在不同的操作系统上运行而...

    JVM系列之String.intern的性能解析

    在Java虚拟机(JVM)中,`String.intern()` 是一个非常特殊且重要的方法,它与字符串常量池紧密相关。字符串常量池是一种内存优化机制,存储了程序中所有的字符串字面值和通过 `intern()` 方法添加的字符串。这个池...

    [jvm]深入JVM(一):从

    [jvm]深入JVM(一):从"abc"=="abc"看java的连接过程收藏 一般说来,我不关注java底层的东西,这次是一个朋友问到了,注意不光是 System.out.println("abc"=="abc");返回true, System.out.println(("a"+"b"+"c")....

    jdk,jvm源码

    Java虚拟机(JVM)是Java程序运行的核心,它负责解释和执行字节码,为Java应用程序提供了一个跨平台的运行环境。JDK(Java Development Kit)包含了开发和运行Java程序所需的所有工具,包括JVM。当我们谈论"jdk,jvm...

    JVM原理讲解和调优,详细讲解JVM底层

    JVM的垃圾回收机制是为了自动释放不再被引用的对象所占用的内存,它涉及多个回收算法和策略。垃圾回收器会周期性地检查堆中的对象,标识出不再使用的对象,并回收其占用的空间。新生代和旧生代的堆结构设计是垃圾...

    JVM必知必会

    - **垃圾收集**:指JVM回收那些不再被使用的对象占用的内存空间。 - **垃圾收集器**:不同垃圾收集器有不同的算法和特点,如G1收集器、CMS收集器等。 - **垃圾收集算法**:标记-清除、复制、标记-整理、分代收集等。...

    开发测试环境Docker及JVM内存限制部署方案

    该文档描述了开发测试环境中Docker及JVM内存限制部署方案

    jvm支持最大线程数简单测试

    jvm支持最大线程数简单测试 jvm支持最大线程数简单测试是非常重要的知识点,下面将详细介绍该知识点。 1. JVM支持的最大线程数 jvm支持的最大线程数是受多种因素影响的,包括java堆内存大小、Thread的Stack内存...

    java 查看JVM中所有的线程的活动状况

    在Java编程环境中,了解JVM(Java虚拟机)中所有线程的活动状态对于调试多线程程序至关重要。本文将详细讲解如何查看JVM中的线程活动情况,并提供相关示例代码。 首先,Java提供了`java.lang.management....

Global site tag (gtag.js) - Google Analytics