java中的重复堆栈跟踪检测

java中的重复堆栈跟踪检测,java,hash,duplicates,stack-trace,Java,Hash,Duplicates,Stack Trace,我试图找到一个好的哈希函数或实用程序代码,可以用来检查堆栈跟踪是否已经存在 到目前为止,我使用一个简单的逻辑进行比较 前2000个字符和另2000个字符,从“原因”部分开始(如果存在) 这将完成这项工作,但是,需要一个更具技术性的解决方案 比如: 初始化: StackTraceElement[] previous = null; StackTraceElement[] current = null; 假设此代码从main的某个地方开始: StackTraceElement[]

我试图找到一个好的哈希函数或实用程序代码,可以用来检查堆栈跟踪是否已经存在

到目前为止,我使用一个简单的逻辑进行比较 前2000个字符和另2000个字符,从“原因”部分开始(如果存在)


这将完成这项工作,但是,需要一个更具技术性的解决方案

比如:

初始化:

StackTraceElement[] previous = null;
    StackTraceElement[] current = null;
假设此代码从main的某个地方开始:

    StackTraceElement[] stackTrace = Thread.getCurrentThread().getStackTrace();
    if( previous == null )
    {
       previous = stackTrace;
    }
    else if( current == null )
    {
       current = stackTrace;
    }



    if ( Arrays.equals( current, previous ) )
    {
        duplicateStackTrace = true;
    }


    previous = current;
    current = null;
假设StackTraceeElement的内置equals()函数适用于您:

public boolean equals(Object obj) {
        if (obj==this)
            return true;
        if (!(obj instanceof StackTraceElement))
            return false;
        StackTraceElement e = (StackTraceElement)obj;
        return e.declaringClass.equals(declaringClass) &&
            e.lineNumber == lineNumber &&
            Objects.equals(methodName, e.methodName) &&
            Objects.equals(fileName, e.fileName);
    }

比如说:

初始化:

StackTraceElement[] previous = null;
    StackTraceElement[] current = null;
假设此代码从main的某个地方开始:

    StackTraceElement[] stackTrace = Thread.getCurrentThread().getStackTrace();
    if( previous == null )
    {
       previous = stackTrace;
    }
    else if( current == null )
    {
       current = stackTrace;
    }



    if ( Arrays.equals( current, previous ) )
    {
        duplicateStackTrace = true;
    }


    previous = current;
    current = null;
假设StackTraceeElement的内置equals()函数适用于您:

public boolean equals(Object obj) {
        if (obj==this)
            return true;
        if (!(obj instanceof StackTraceElement))
            return false;
        StackTraceElement e = (StackTraceElement)obj;
        return e.declaringClass.equals(declaringClass) &&
            e.lineNumber == lineNumber &&
            Objects.equals(methodName, e.methodName) &&
            Objects.equals(fileName, e.fileName);
    }

我过去曾使用堆栈跟踪哈希来处理“bucket”异常,以便更容易地看到哪些错误最频繁。实现堆栈跟踪哈希的最简单、最直接的方法如下:

public static int computeStackTraceHash(StackTraceElement[] trace) {
  return Arrays.hashCode(trace);
}
public static int computeStackTraceHash(StackTraceElement[] trace) {
  List<Object> components = new ArrayList<>();

  for (StackTraceElement el : trace) {
    if (includeElement(el)) { // decide whether we're including this element
      components.add(el.getClassName());
      components.add(el.getMethodName());
    }
  }

  return components.hashCode();
}
<>但是,值得注意的是,<代码> StasTraceEngult.HASCODE()/Script >引入了一些您可能希望考虑的皱纹。
StackTraceeElement
的哈希代码是通过将以下内容XOR在一起计算得出的:

  • fileName.hashCode()
  • 行号
  • declaringClass.hashCode()
  • methodName.hashCode()
(如果文件名、声明类或方法名未知,则相应的属性将为null,并使用0代替哈希进行计算。)

如果动态生成的类是堆栈跟踪的一部分(与Spring之类的库很常见),则跟踪中某些类的名称可能是随机的,这将破坏哈希。因此,您可能希望在跟踪中检测这些类并忽略它们。您可能还希望在散列计算中省略行号,这将使您的“bucket”更能容忍代码中的微小更改。你的个人情况可能需要考虑其他的事情。因此,这可以改变您的计算,使其看起来像这样:

public static int computeStackTraceHash(StackTraceElement[] trace) {
  return Arrays.hashCode(trace);
}
public static int computeStackTraceHash(StackTraceElement[] trace) {
  List<Object> components = new ArrayList<>();

  for (StackTraceElement el : trace) {
    if (includeElement(el)) { // decide whether we're including this element
      components.add(el.getClassName());
      components.add(el.getMethodName());
    }
  }

  return components.hashCode();
}
public static int computeStackTraceHash(StackTraceElement[]跟踪){
List components=new ArrayList();
用于(StackTraceElement el:trace){
如果(includeElement(el)){//决定是否包含此元素
add(el.getClassName());
add(el.getMethodName());
}
}
返回components.hashCode();
}

我过去曾使用堆栈跟踪哈希来处理“bucket”异常,以便更容易地看到哪些错误最常见。实现堆栈跟踪哈希的最简单、最直接的方法如下:

public static int computeStackTraceHash(StackTraceElement[] trace) {
  return Arrays.hashCode(trace);
}
public static int computeStackTraceHash(StackTraceElement[] trace) {
  List<Object> components = new ArrayList<>();

  for (StackTraceElement el : trace) {
    if (includeElement(el)) { // decide whether we're including this element
      components.add(el.getClassName());
      components.add(el.getMethodName());
    }
  }

  return components.hashCode();
}
<>但是,值得注意的是,<代码> StasTraceEngult.HASCODE()/Script >引入了一些您可能希望考虑的皱纹。
StackTraceeElement
的哈希代码是通过将以下内容XOR在一起计算得出的:

  • fileName.hashCode()
  • 行号
  • declaringClass.hashCode()
  • methodName.hashCode()
(如果文件名、声明类或方法名未知,则相应的属性将为null,并使用0代替哈希进行计算。)

如果动态生成的类是堆栈跟踪的一部分(与Spring之类的库很常见),则跟踪中某些类的名称可能是随机的,这将破坏哈希。因此,您可能希望在跟踪中检测这些类并忽略它们。您可能还希望在散列计算中省略行号,这将使您的“bucket”更能容忍代码中的微小更改。你的个人情况可能需要考虑其他的事情。因此,这可以改变您的计算,使其看起来像这样:

public static int computeStackTraceHash(StackTraceElement[] trace) {
  return Arrays.hashCode(trace);
}
public static int computeStackTraceHash(StackTraceElement[] trace) {
  List<Object> components = new ArrayList<>();

  for (StackTraceElement el : trace) {
    if (includeElement(el)) { // decide whether we're including this element
      components.add(el.getClassName());
      components.add(el.getMethodName());
    }
  }

  return components.hashCode();
}
public static int computeStackTraceHash(StackTraceElement[]跟踪){
List components=new ArrayList();
用于(StackTraceElement el:trace){
如果(includeElement(el)){//决定是否包含此元素
add(el.getClassName());
add(el.getMethodName());
}
}
返回components.hashCode();
}

如何定义堆栈跟踪的副本?(class.method.lineNumber)的重复数组是否会将堆栈跟踪转换为字符串,然后使用该字符串为您进行比较工作?因为此代码必须在移动应用程序中运行,所以性能和内存都是一个问题。转换整个堆栈跟踪并与另一个作为字符串进行比较的操作似乎非常昂贵。如何定义堆栈跟踪的副本?(class.method.lineNumber)的重复数组是否会将堆栈跟踪转换为字符串,然后使用该字符串为您进行比较工作?因为此代码必须在移动应用程序中运行,所以性能和内存都是一个问题。转换整个堆栈跟踪并将其与另一个作为字符串进行比较似乎非常昂贵的操作这对于在移动应用程序中运行代码来说是很好的,但是这看起来是非常昂贵的操作。特别是当我有一个堆栈跟踪注册表要与之进行比较时当你已经有了堆栈跟踪注册表,我认为它只是一个堆栈跟踪列表时,你不能使用array.equals()?可能是我遗漏了一些东西,这对在移动应用程序中运行代码来说是很好的,但这看起来像是昂贵的操作。特别是当我有一个堆栈跟踪注册表要与之进行比较时当你已经有了堆栈跟踪注册表,我认为它只是一个堆栈跟踪列表时,你不能使用array.equals()?也许我错过了什么