是否有工具可以在不加载完整hprof文件的情况下分析大型Java堆转储?(Are there tools to analyse large Java heap dumps without loading the complete hprof file?)
我使用Eclipse MAT来分析hprof文件。 这是非常好的,但如果你有2Gb堆转储,那么你需要运行带有2Gb +堆大小的MAT,以便能够加载完整的堆转储。
我想知道是否有人知道可以分析一个2Gb hprof文件而不使用那么多内存本身的工具(例如,它不会加载完整的文件,但以某种方式遍历它)? 如果在客户服务器上生成hprof文件,这将非常有用,因为我可以在服务器上运行一些分析,而不是试图通过VPN复制2Gb文件。
I use Eclipse MAT to analyse hprof files. It is very good but if you have a 2Gb heap dump then you need to run MAT with a 2Gb+ heap size itself to be able to load the complete heap dump.
I was wondering if anyone knows of a tool that could analyse a 2Gb hprof file without using that much memory itself (e.g. it doesn't load the complete file but somehow walks through it)? This would be useful if a hprof file gets generated on a customer server as I could then run some analysis on the server instead of trying to copy a 2Gb file over a VPN.
原文:https://stackoverflow.com/questions/1795778
最满意答案
问题是子线程上的异常需要报告回主线程。 除非您将读取器和编写器放在不同的线程中,否则这可能很棘手。
我这样做的方法是将两个部分包装在
ExecutionCompletionService
- 如下所示:public void process(InputStream xmlStream) { ExecutorService threadPool = Executors.newFixedThreadPool(2); ExecutorCompletionService<Void> ecs = new ExecutorCompletionService<>(threadPool); final BufferedInputStream bufferedXmlStream = new BufferedInputStream(xmlStream); PipedInputStream pipedJsonInputStream = new PipedInputStream(); final PipedOutputStream jsonStream = new PipedOutputStream(pipedJsonInputStream); ecs.submit( new Callable<Void>() { @Override public Void call() { // put your code that writes data to the outputstream here. try { XML.toJson(bufferedXmlStream, jsonStream, true); } catch (Exception e) { e.printStackTrace(); throw e; } return null; } }); ecs.submit( new Callable<Void>() { @Override public Void call() { try { // use reader to further process json in main thread... parseJsonStream(reader); } finally { reader.close(); jsonStream.close(); } return null; } }); // Wait for all tasks to be done. // Kill the other thread if one hits an exception. try { for (int i = 0; i < 2; ++i) { ecs.take().get(); } } finally { threadPool.shutdownNow(); } }
The problem is that the exception on the child thread needs to get reported back to the main thread. This can be tricky to do unless you put both the reader and writer in separate threads.
The way I do this is to wrap both pieces in an
ExecutionCompletionService
- like this:public void process(InputStream xmlStream) { ExecutorService threadPool = Executors.newFixedThreadPool(2); ExecutorCompletionService<Void> ecs = new ExecutorCompletionService<>(threadPool); final BufferedInputStream bufferedXmlStream = new BufferedInputStream(xmlStream); PipedInputStream pipedJsonInputStream = new PipedInputStream(); final PipedOutputStream jsonStream = new PipedOutputStream(pipedJsonInputStream); ecs.submit( new Callable<Void>() { @Override public Void call() { // put your code that writes data to the outputstream here. try { XML.toJson(bufferedXmlStream, jsonStream, true); } catch (Exception e) { e.printStackTrace(); throw e; } return null; } }); ecs.submit( new Callable<Void>() { @Override public Void call() { try { // use reader to further process json in main thread... parseJsonStream(reader); } finally { reader.close(); jsonStream.close(); } return null; } }); // Wait for all tasks to be done. // Kill the other thread if one hits an exception. try { for (int i = 0; i < 2; ++i) { ecs.take().get(); } } finally { threadPool.shutdownNow(); } }
相关问答
更多-
问题是子线程上的异常需要报告回主线程。 除非您将读取器和编写器放在不同的线程中,否则这可能很棘手。 我这样做的方法是将两个部分包装在ExecutionCompletionService - 如下所示: public void process(InputStream xmlStream) { ExecutorService threadPool = Executors.newFixedThreadPool(2); ExecutorCompletionService
ecs = ne ... -
JB Nizet的答案没问题,但它只使用map副作用,而不是地图操作,这有点奇怪。 有一种方法可以在你对某些事物的副作用感兴趣时使用,例如抛出异常: peek 。 List
filtered = list.stream() .peek(Objects::requireNonNull) .filter(predicate) .collect(Collectors.toList()); 如果你想要你自己的异常,只需在其中放入一个lamb ... -
一个PipedInputStream只会在数据被连接到的输出流写入时使数据可用。 只要您从输入流中读取输入流的速度与从输出流接收数据一样快,就不会有太多的数据需要缓冲。 如果这没有帮助,您需要提供更多关于您使用管道输入流进行的操作的信息 - 连接到哪个输出流以及从中读取什么内容? 编辑:你还没有说什么是从你的PipedInputStream阅读。 一定是,否则PipedOutputStream会阻塞 - PipedInputStream只有一个相当小的缓冲区(默认情况下)。 A PipedInputStre ...
-
您可以使用Throwable.addSuppressed(Throwable) ,它允许记录任意数量的throwables(以后可以通过getSuppressed()获取),并且在语义上比将其他throwables记录为“cause”更合适。 由于这是对其中一个throwables的一种修改,因此reduce不是正确的操作(并且它不会在并行操作中提供预期的结果)。 这看起来不像是需要对大量元素进行优化的操作,因此,最佳解决方案是直接将所有元素收集到List并使用 if(!listOfAllException ...
-
Java流:根据流中的值抛出异常(Java streams: throwing exception from stream depending upon value in stream)[2021-11-24]
您可以检查是否有任何元素通过了您的过滤器,并且如果没有:使用Optional的orElseThrow引发异常: Integer match = intList.stream() .filter(i -> i > 40) .findAny() .orElseThrow(...); 当然,这只会给你一个在不抛出异常时通过过滤器的元素,所以我不确定它是否正是你想要的。 You could check if there's any ele ... -
用这个: java -jar `find / -type f -name "R*.jar" -printf '%T@ %p\n' | sort -k 1nr | sed 's/^[^ ]* //' | head -n 1` -debug 这个 sort命令答案的功劳。 Use this: java -jar `find / -type f -name "R*.jar" -printf '%T@ %p\n' | sort -k 1nr | sed 's/^[^ ]* //' | head -n 1` -de ...
-
java中的字节流(Byte streams in java)[2023-11-16]
我已经读过字节流不支持unicode字符。 要么你使用了糟糕的信息来源,要么你可能误解了一些东西。 字节流支持字节。 因此,字节流支持可以用字节表示的任何内容 。 视频,文本,图片,音乐......如果字节流不支持它,则根本不能在数字计算机中使用它。 在简单的1和0序列中表示那些东西的技巧是使用商定的规则。 您可以根据特定规则对文本进行编码,然后接收方可以使用相同的规则对其进行解码。 "Русский язык"可以表示为支持西里尔字符的任何编码中的字节。 在unicode的任何编码中:UTF-8,UTF- ... -
Node.js读取管道流(Node.js reading piped streams)[2023-08-08]
var unzipStream = zlib.createUnzip() unzipStream.on('data', myDataHandler).on('end', myEndHandler) fs.createReadStream('log.gz').pipe(unzipStream) 这将为您提供data和end事件。 由于它是日志数据,您可能还会发现拆分对于逐行获取事件非常有用。 var unzipStream = zlib.createUnzip() unzipStream.on('data' ... -
使用setEmbeddedData()函数将selectedChoiceLower分配给新的或现有的嵌入数据变量( 请参阅文档 )。 然后,您可以在以后的问题中使用嵌入的字段变量。 javascript: setEmbeddedData('lower', selectedChoiceLower); 嵌入字段代码: ${e://Fields/lower} 警告:将用户生成的文本放入javascript非常危险! Qualtrics不会进行任何转义。 如果用户在其文本中放入“或”,它将直接放入javascrip ...
-
问题是输出没有被刷新 请参阅http://docs.oracle.com/javase/7/docs/api/java/io/PipedOutputStream.html#flush() The issue is that the output is not being flushed see http://docs.oracle.com/javase/7/docs/api/java/io/PipedOutputStream.html#flush()