e.printStackTrace() 太多,造成微服务请求不通,nginx访问不教程
e.printStackTrace();
<br></br>先查看下源码
<br></br><br></br>如图片中1所示,使用的是 PrintStreamOrWriter<br></br><br></br>
public void printStackTrace() {
printStackTrace(System.err);
}
/**
* Prints this throwable and its backtrace to the specified print stream.
*
* @param s {@code PrintStream} to use for output
*/
public void printStackTrace(PrintStream s) {
printStackTrace(new WrappedPrintStream(s));
}
private void printStackTrace(PrintStreamOrWriter s) {
// Guard against malicious overrides of Throwable.equals by
// using a Set with identity equality semantics.
Set<Throwable> dejaVu =
Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
dejaVu.add(this);
synchronized (s.lock()) {
// Print our stack trace
s.println(this);
StackTraceElement[] trace = getOurStackTrace();
for (StackTraceElement traceElement : trace)
s.println("\tat " + traceElement);
// Print suppressed exceptions, if any
for (Throwable se : getSuppressed())
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
// Print cause, if any
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
}
}
<br></br> ,而这来源于 PrintStream,而 PrintStream 又继承 FilterOutputStream ,是文件输出流,会肯定会影响内存的变动
ublic class PrintStream extends FilterOutputStream
implements Appendable, Closeable
{
private final boolean autoFlush;
private boolean trouble = false;
private Formatter formatter;
/**
* Track both the text- and character-output streams, so that their buffers
* can be flushed without flushing the entire stream.
*/
private BufferedWriter textOut;
private OutputStreamWriter charOut;
/**
* requireNonNull is explicitly declared here so as not to create an extra
* dependency on java.util.Objects.requireNonNull. PrintStream is loaded
* early during system initialization.
*/
private static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
}
而图片中二所示的lock锁,锁住这个流对象,就是占用住了内存不让进行gc回收,先输出打印,
跟踪s.println(this) 也就是PrintStream的方法,发现是会使用bufferedwriter和outputstream
/**
* Prints an Object and then terminate the line. This method calls
* at first String.valueOf(x) to get the printed object's string value,
* then behaves as
* though it invokes <code>{@link #print(String)}</code> and then
* <code>{@link #println()}</code>.
*
* @param x The <code>Object</code> to be printed.
*/
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}<br></br><br></br>
/**<br></br> * Prints a string. If the argument is <code>null</code> then the string<br></br> * <code>"null"</code> is printed. Otherwise, the string's characters are<br></br> * converted into bytes according to the platform's default character<br></br> * encoding, and these bytes are written in exactly the manner of the<br></br> * <code>{@link #write(int)}</code> method.<br></br> *<br></br> * @param s The <code>String</code> to be printed<br></br> */<br></br>public void print(String s) {<br></br> if (s == null) {<br></br> s = "null";<br></br> }<br></br> write(s);<br></br>}
<br></br>private void write(String s) {<br></br> try {<br></br> synchronized (this) {<br></br> ensureOpen();<br></br> textOut.write(s);<br></br> textOut.flushBuffer();<br></br> charOut.flushBuffer();<br></br> if (autoFlush && (s.indexOf('\n') >= 0))<br></br> out.flush();<br></br> }<br></br> }<br></br> catch (InterruptedIOException x) {<br></br> Thread.currentThread().interrupt();<br></br> }<br></br> catch (IOException x) {<br></br> trouble = true;<br></br> }<br></br>}
后又获取 StackTraceElement ,也就是获取方法调用者的具体信息 的。 循环打印
然后又获取报错的异常数据 Throwable的数组, 循环打印
java中e.printStackTrace()不要使用,请使用logger记录
===========================================================================================================================