这是一个困扰了我接近半个月的生产bug。当问题出现后,采取的措施分别是:打印日志,再仍然查不出问题后,改用其他方式实现,先保证不会对用户使用该系统数据照成影响。
在经过两天时间的跟踪,终于找到问题的根源。详细记录如下:
代码在字符串时逻辑里面用到了
StringUtils.contains()
方法,而这个方法主要是调用
String.indexOf()
方法,
如“
,A,B,C,D,".indexOf("A")
> 0
返回
true
;
"A,B,C,D,".indexOf("E")
返回
false
。经过代码分析,结论是这个方法在参数完全一样的情况下运行结果出现了不一致的情况。在
oracle
的官网上查找
jdk
的
bug
库发现了与
String.indexOf
()方法相关的重要的
bug
记录:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6935535
内容是:
String.indexOf() returns incorrect result on x86 with SSE4.2
。决定在生产上重现这个
bug
,于是把如下的代码放在生产上测试。
测试代码:
public class Test{
static int IndexOfTest(String str) {
return str.indexOf("1111111111111xx1x");
}
public static void main(String args[]) {
String str = "1111111111111xx1111111111111xx1x";
str = str.substring(0, 31);
int idx = IndexOfTest(str);
System.out.println("IndexOf(" + "1111111111111xx1x" + ") = " + idx + " in " + str);
}
}
这段代码正确的结果应该是:-1
,经过两次测试结果如下:
命令:java test
输出:IndexOf(1111111111111xx1x)= -1 in 1111111111111xx1111111111111xx1x
命令:java -XX:+UseSSE42Intrinsics -Xcomp test
输出:IndexOf(1111111111111xx1x)= 15 in 1111111111111xx1111111111111xx1x
生产上的
java
版本:
java version "1.6.0_20"
,
CPU
架构:
x86_64 GNU/Linux
,指令集包含:
sse4_2
然后,又在
java version "1.6.0_25"
生产机器上运行,结果是正确的。
解决indexOf的方案,可采用如下方法中的一种:
1.
升级
JDK
版本到
1.6.0_25
;
2.
在
java
启动行加上参数:
-XX:-UseSSE42Intrinsics
。
分享到:
相关推荐
例如,`length()`返回字符串的长度,`charAt(int index)`获取指定位置的字符,`substring(int beginIndex, int endIndex)`截取子字符串,`indexOf(String str)`查找子字符串第一次出现的位置,`equals(Object an...
ajax 与 java 之间使用 json 交换数据,JSON到Java 对象的转换,Java对象到JSON的转换。 JSONObject object=new JSONObject(javaBean); String jsonStr=object.toString();
在Java编程语言中,`String`类是处理文本数据的核心类,它提供了丰富的API来执行各种操作,如创建、比较、查找、替换、截取等。在这个程序中,主要展示了`String`类的一些常见方法,如`substring()`、`split()`等。...
- `indexOf(String str)`/`lastIndexOf(String str)`:分别查找指定字符串第一次出现和最后一次出现的索引。 - `substring(int beginIndex)`/`substring(int beginIndex, int endIndex)`:截取字符串的一部分。 -...
【JAVA】笔记(8)--- java.lang.String 精讲(csdn)————程序
使用了`#include<stdio.h>`和`#include<string.h>`头文件,前者包含基本的输入输出函数,后者包含了`strlen`函数,用于计算字符串的长度。此外,还定义了一个宏`M=10005`,用来设置数组的最大长度。 在`main`函数中...
public void findContract(String filePath, HttpServletResponse response){ File file=new File(filePath); if (file.exists()){ byte[] data = null; try { FileInputStream input = new FileInputStream...
在定义回复内容时,我们需要指定输出的文字编码方式,可以使用 `string.encode()` 函数来指定输出的文字编码方式,例如 `string.encode('gb2312')`、`string.encode('utf-8')`、`string.encode('gbk')` 等。...
在C++中,`std::string`类提供了一些方法来处理字符串中的字符大小写转换。在处理文本数据时,这是一项常见的操作,特别是在文本分析、用户输入验证或格式化输出等场景。`std::string`类没有直接提供将整个字符串...
【标题】"安卓Android源码——GestureDemo.zip"是一个关于Android手势识别的示例项目,它可以帮助开发者理解和实现用户在Android设备上的各种手势操作。在这个项目中,开发者将学习到如何利用Android SDK中的...
在Java编程语言中,String是最常用的类之一,用于处理文本数据。本文主要分析两种创建String对象的...在实际编程中,推荐使用字符串字面量或`String.intern()`方法来优化内存使用,特别是对于大量重复字符串的情况。
1. **数据存储**:Bundle支持多种数据类型,如基本类型(int, String, boolean等),数组,集合(List, Map等)以及Parcelable和Serializable接口实现的类。通过putXXX和getXXX方法,开发者可以轻松地添加和获取数据...
2. **主方法**:`main()` 方法是Java程序的入口点,`public static void main(String[] args)` 是每个Java应用程序都必须包含的函数。在这里,有两个`main` 方法,通常一个程序只有一个主方法,但这里为了演示方便,...
在创建`Column`对象时,注意到有一个字符串格式化操作,`String.format(columnName, t, t)`。这里`columnName`的定义是`"IF(%s is not null,%s,'')"`,这是一个典型的SQL三元运算符,用于检查某个列值是否为null,...
pages.add(String.valueOf(i)); } reader.selectPages(StringUtils.join(pages, ",")); // 删除第一页 PdfStamper stamp = new PdfStamper(reader, new FileOutputStream("E:/test2.pdf")); // 重新输出为PDF ...
String cc = new String(c); //密文 String System.out.println(cc); } } ``` 这个程序将密文转换为明文,通过将每个字符向左移动 3 位来实现。这里的 3 是一个固定的偏移量,可以根据需要进行调整。 明文->密文...
在项目"安卓Android源码——SharePreferencesSample.rar"中,我们可以深入理解并学习SharedPreferences的工作原理及其应用场景。 1. **SharedPreferences介绍** SharedPreferences是一个接口,它允许应用程序存储...
一是使用`memset`函数,这是一个来自`<string.h>`库的函数,可以快速将数组或内存区域的每个元素设为特定值,例如初始化数组为零。二是使用`sort`函数,这通常是一个库函数,可以对数组进行快速升序排序,例如在给定...
Date birthdayDate = simpleDateFormat.parse(String.valueOf(birthday)); int age = currentYear - (birthdayDate.getYear() + 1900); int myDay = birthdayDate.getDay(); int myMonth = birthdayDate....
在Java编程语言中,`String`类是一个核心的类,它位于`java.lang`包中,是所有Java程序的基础。`String`类代表不可变的字符序列,这意味着一旦创建了一个`String`对象,它的内容就不能被修改。这是由`String`类的`...