我刚接受采访,并被要求用Java 创建内存泄漏.
毋庸置疑,我觉得自己很傻,甚至不知道如何开始创建一个.
一个例子是什么?
考虑到这一点的代码,我可以绝对肯定的是,finally块总是执行,不管something()是什么?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("I don't know if this will get printed out");
}
Run Code Online (Sandbox Code Playgroud) 假设我们有Java代码:
Object arr = Array.newInstance(Array.class, 5);
Run Code Online (Sandbox Code Playgroud)
那会跑吗?作为进一步的说明,如果我们尝试这样的事情怎么办:
Object arr1 = Array.newInstance(Array.class, 2);
Object arr2 = Array.newInstance(String.class, 4);
Object arr3 = Array.newInstance(String.class, 4);
Array.set(arr1, 0, arr2);
Array.set(arr1, 1, arr3);
Run Code Online (Sandbox Code Playgroud)
那么arr1会是一个2D数组,相当于:
String[2][4] arr1;
Run Code Online (Sandbox Code Playgroud)
怎么样:如果我们在运行时之前不知道这个数组的尺寸怎么办?
编辑:如果这有帮助(我相信它会...)我们试图从表单的字符串解析未知维度的数组
[value1, value2, ...]
Run Code Online (Sandbox Code Playgroud)
要么
[ [value11, value12, ...] [value21, value22, ...] ...]
Run Code Online (Sandbox Code Playgroud)
等等
编辑2:如果有人像我一样愚蠢尝试这个垃圾,这里是一个至少编译和运行的版本.逻辑是否合理完全是另一个问题......
Object arr1 = Array.newInstance(Object.class, x);
Object arr11 = Array.newInstance(Object.class, y);
Object arr12 = Array.newInstance(Object.class, y);
...
Object arr1x = Array.newInstance(Object.class, y);
Array.set(arr1, 0, arr11);
Array.set(arr1, 1, arr12);
...
Array.set(arr1, x-1, arr1x);
Run Code Online (Sandbox Code Playgroud)
等等.它只需要是一个巨大的嵌套对象数组
我现在正在调试一个程序,每个外部进程有两个线程,这两个线程继续使用while ((i = in.read(buf, 0, buf.length)) >= 0)循环读取Process.getErrorStream()和Process.getInputStream().
有时,当外部进程因JVM崩溃而崩溃时(请参阅这些hs_err_pid.log文件),那些读取该外部进程的stdout/stderr的线程开始消耗100%的CPU并且永远不会退出.循环体没有被执行(我在那里添加了一个日志语句),所以无限循环似乎在本机方法中java.io.FileInputStream.readBytes.
我在Windows 7 64位(jdk1.6.0_30 64位,jdk1.7.0_03 64位)和Linux 2.6.18(jdk1.6.0_21 32位)上重现了这一点.有问题的代码在这里,就像这样使用.请参阅这些链接以获取完整代码 - 以下是有趣的内容:
private final byte[] buf = new byte[256];
private final InputStream in;
...
int i;
while ((i = this.in.read(this.buf, 0, this.buf.length)) >= 0) {
...
}
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪看起来像
"PIT Stream Monitor" daemon prio=6 tid=0x0000000008869800 nid=0x1f70 runnable [0x000000000d7ff000]
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:220)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
- locked …Run Code Online (Sandbox Code Playgroud) 我需要配置创建jvm崩溃日志的位置.我喜欢他们的名字(hs_err_pid.log),但我希望他们在特定的文件夹中创建.
在这里你可以看到你可以使用
-XX:ErrorFile=./hs_err_pid<pid>.log
Run Code Online (Sandbox Code Playgroud)
param用于设置创建的FILE,但是如果将其设置为文件夹,那么使用原始命名约定在该文件夹中创建文件,它不起作用,将被忽略.
我一直在通过崩溃jvm 1.6来测试这个问题,使用这个:PathDasher dasher = new PathDasher(null);
有谁知道实现这个目标的方法?
如果我使用JDK1.8_40或更新版本(Oracle或OpenJDK执行相同操作),以下代码和对话框调整大小将使应用程序崩溃(尝试过Windows 7,x64,64位JDK)
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JDialog dialog = new JDialog();
dialog.add(new JPanel());
dialog.setVisible(true);
dialog.setBounds(100, 100, 100, 100);
final JWindow dependentWindow = getjWindow(dialog);
dependentWindow.setVisible(true);
dependentWindow.setBounds(100, 100, 100, 100);
Timer t = new Timer(300, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dependentWindow.setVisible(!dependentWindow.isVisible());
}
});
t.start();
}
});
} …Run Code Online (Sandbox Code Playgroud) 针对Java VM有一个类似的问题,但我没有找到.net的问题(如果我遗漏了某些内容,请关闭并标记为重复).
那么 - 没有讨厌的非托管互操作可能吗?崩溃我的意思是真正的"xxx.exe已经停止工作"而不是StackOverflow-或OutOfMemoryException.
我认为这是不可能的,除非遇到VM本身的错误.
如何在Java中重现EXCEPTION_STACK_OVERFLOW错误.
PS:我不是在谈论优雅地关闭JVM的Java中的StackOverflowError错误.我在讨论error.log中的EXCEPTION_STACK_OVERFLOW,这会导致JVM崩溃.
我正在使用JNI,当由于目标应用程序中的错误而发生崩溃时,会生成hs_err_pid*.log文件.我想更改存储该文件的默认位置.现在,通过搜索我明白这可以使用JVM参数-XX:ErrorFile来实现.
该文件说,该参数默认为./hs_err_pid <PID >.LOG
现在,当我覆盖默认值时,如何告诉JVM仍然在文件名中包含进程ID?我显然试图将targetDir/hs_err_pid <pid >.log作为命令行参数,但这导致整个参数被忽略(并且文件存储到默认位置,即工作目录).如果我只说targetDir/hs_err_pid.log文件存储在我想要的位置,但是没有将文件附加到进程ID.
任何建议,将不胜感激.
在我过去的一次采访中,有人让我写一个代码来破坏JVM.我说System.exit().它是否正确?还有更好的答案吗?
澄清:我可以在开发和部署期间包含我的代码.并不是JVM已经在运行,我必须编写一个黑客代码来破坏其他JVM.
我见过类似的问题:如何崩溃一个jvm和最短代码以提高SIGSEGv。
有一些Java代码可以生成SIGSEGV,例如:
final Constructor<Unsafe> unsafeConstructor = Unsafe.class.getDeclaredConstructor();
unsafeConstructor.setAccessible(true);
final Unsafe unsafe = unsafeConstructor.newInstance();
System.out.println(unsafe.getAddress(0));
Run Code Online (Sandbox Code Playgroud)
并生成SIGSEGV类型的V(VM帧)。
# JRE version: Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# V [jvm.dll+0x1e2440]
Run Code Online (Sandbox Code Playgroud)
并且Crash in Compiled Code根据https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/crashes001.html进行。
我想知道是否仍然会产生类型化的J分段错误。
而且我已经看到了一些lib问题,例如JVM崩溃。(所以它表明可以手动生成?)