I tried to read a text file which have only one line. File size is over 50Mb. When I tried to read it using the following code it gives
java.lang.outofmemory exception jvm
heap size insufficient
I change the java heap memory to 1GB . But still it gives the same exception.
set JAVA_OPTS=-Xms1024m -Xmx1024m
I use foollowing code pragment to read the file.
BufferedReader Filein1=new
BufferedReader(new FileReader( new
File( "C:\ABC\MsgStream.txt" )));
s=Filein1.readLine();
Can some one please tell me how to overcome this problem. Thanks in advance.
The JAVA_OPTS environment variable is only respected by certain applications (for example the wrapper scripts that are typically used to launch Tomcat). The java command doesn't pay any attention to it.
You need to put the options on the java command line ... before the classname; e.g.
java -Xms1024m -Xmx1024m ... some.pkg.MainClass ...
(A 1Gb heap should be more than adequate for buffering a 50Mb file.)
Are JAVA_OPTS actually being run in the output? You may need to actually put them on the command line you're running, or include $JAVA_OPTS on it.
It's _JAVA_OPTIONS not JAVA_OPTS
If you have a class like
public class Test {
public static void main(String args[]) {
System.out.println("value : " + System.getProperty("foo"));
}
}
then you should get
> set _JAVA_OPTIONS=-Dfoo=bar
> java Test
> value : bar
Related
Can anybody help me in following problem:
if I am specifying java args while running my program through java command then if I check my java process using ps -ef command it shows me a long output including all vm arguments .I just want to pass a single property file as system argument and then want to read all vm and program arguments from it ,so that ps command for my process only shows config file in path and ps output is shorten
You can use a command line arguments file.
Let's say you have a file called args (an arbitrary name) containing your arguments
-Xmn25m
-Xmx51m
-XX:+UseParallelGC
And a java program that, for example, prints the maximum size for the heap
public class ArgsTest {
public static void main(String args[]) {
System.out.println(Runtime.getRuntime().maxMemory());
}
}
You can pass the arguments in the file by prefixing the file name with #, so for example running the program this way
java #args ArgTest.java
prints 51380224
Let's change the arguments file to increase the heap maximum size to 512 MB
-Xmn25m
-Xmx512m
-XX:+UseParallelG
The same program run with the same command line now prints 528482304
From Java 9 onwards VM parameters can be put into a java Command-Line Argument File (https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html#java-command-line-argument-files, Link from Frederico).
Info on option Xms:
-Xms size
Sets the minimum and the initial size (in bytes) of the heap.
This value must be a multiple of 1024 and greater than 1 MB.
Append the letter k or K to indicate kilobytes, m or M to
indicate megabytes, or g or G to indicate gigabytes.
The following examples show how to set the size of allocated
memory to 6 MB using various units:
-Xms6291456
-Xms6144k
-Xms6m
java command-line argument file (myargumentfile) contains only one line:
-Xms10m
java call:
java #myargumentfile <Class Name>
To hide other command line parameters by using a property file and to show the input parameter:
Properties file (myprop.properties) contains two lines:
value1="property value 1"
value2=property value 2
Java source (Prop.java):
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ManagementFactory;
public class Prop {
public static void main(String[] args) {
Properties prop = new Properties();
try {
// load a properties file from class path, inside static method
prop.load(Prop.class.getClassLoader().getResourceAsStream(args[0]));
System.out.println(prop.getProperty("value1"));
System.out.println(prop.getProperty("value2"));
RuntimeMXBean RuntimemxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = RuntimemxBean.getInputArguments();
arguments.stream().forEach(entry -> System.out.println(entry));
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
The files myargumentfile, Prop.java and myprop.properties are in the same directory. Prop.class will be generated there.
$ javac Prop.java
$ java #myargumentfile Prop myprop.properties
"property value 1"
property value 2
-Xms10m
$
I had batch script which executes TestRun class by taking jvm arguments as shown below
java -cp "./lib/*;./statoil.jar" -DURI=localhost:8080 -DOWUser=abc -DOWPassword=abc123 -DpipelineName=EDMStatOil -Ddatabase=edm -DproviderName=141Provider -DdestinationName=110EDM -DproviderWellName=Serno Grad com.statoil.rts.test.TestRun
But while running batch script getting error:
Error: Could not find or load main class Grad
I know it is treating Grad as class file. But how we can avoid this error while passing jvm argument with space?
Java doesn't care if there is a space in the JVM argument's value, but the terminal will split -DproviderWellName=Serno Grad into two command line arguments and pass those to the java executable.
You have to put quotes around the whole argument:
java "-DproviderWellName=Serno Grad"
In you batch file try setting the variable first and then pass that parameter to the actual command like these.
set WellName="Serno Grad"
java -cp "./lib/*;./statoil.jar" -DURI=localhost:8080 -DOWUser=abc -DOWPassword=abc123 -DpipelineName=EDMStatOil -Ddatabase=edm -DproviderName=141Provider -DdestinationName=110EDM -DproviderWellName=%WellName% com.statoil.rts.test.TestRun
OR
set WellName="Serno Grad"
java -cp "./lib/*;./statoil.jar" -DURI=localhost:8080 -DOWUser=abc -DOWPassword=abc123 -DpipelineName=EDMStatOil -Ddatabase=edm -DproviderName=141Provider -DdestinationName=110EDM -DproviderWellName="%WellName%" com.statoil.rts.test.TestRun
On my system either of them works fine.
try with escape characters -DproviderWellName="\"Serno Grad\""
I want to collect heap dump on JVM crash
So i wrote a simple code
public class Test {
private String name;
public Test(String name) {
this.name = name;
}
public void execute() {
Map<String,String> randomData = new HashMap<String,String>();
for(int i=0;i<1000000000;i++) {
randomData.put("Key:" + i,"Value:" + i);
}
}
public void addData() {
}
public static void main(String args[]) {
String myName = "Aniket";
Test tStart = new Test(myName);
tStart.execute();
}
}
and I am running it as follows
[aniket#localhost Desktop]$ java -cp . -Xms2m -Xmx2m Test
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Test.execute(Test.java:15)
at Test.main(Test.java:25)
I got OutOfMemoryError which I wanted but there is no heap dump in the working directory(like hs_err_pidXXXX.log which I expected). What am I missing? How do I get a heap dump?
Update :
I tried -XX:ErrorFile=. still no use. If above is not the way to get the heap dump(Crash JVM) how can I crash my JVM to get those logs?
You are confusing an exception or error being thrown as a JVM crash.
A JVM crash occurs due to an internal error in the JVM, you cannot trigger this by writing a normal Java program (or should not unless you find a bug)
What you are doing is triggering an Error which means the program continues to run until all the non daemon threads exit.
The simplest tool to examine the heap is VisualVM which comes with the JDK. If you want to trigger a heap dump on an OutOfMemoryError you can use -XX:+HeapDumpOnOutOfMemoryError
Use Jmap
jmap [options] pid
pid is the process id of application
When you see the below
Exception in thread "main" java.lang.OutOfMemoryError
It means your error or exception is handled by the exception handler. This is not a crash.
Eclipse has an awesome Heap Analyzer
Also, you can use jps to get the PID, and then jmap for the heap itself.
In case, you want to crash the JVM, your best guess would be native code.
Find the process id for which you want to take the heap dump
ps -ef | grep java
Once you get PID by running above command run below command to generate heap dump.
jmap -dump:format=b,file=<fileName> <java PID>
You can pass below JVM arguments to your application:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=
This argument will automatically trigger heap dump in the specified 'file-path' when your application experiences OutOfMemoryError. There are 7 different options to take heap dumps from your application:
jmap
-XX:+HeapDumpOnOutOfMemoryError
jcmd
JVisualVM
JMX
Programmatic Approach
Administrative consoles
Details about each option can be found in this article. Once you have captured heap dump, you may use tools like Eclipse Memory Analysis tool, HeapHero to analyze the captured heap dumps.
import java.io.*;
import java.util.*;
public class ReadPropertiesFile {
public static void main(String[] args)throws Throwable{
Properties prop = new Properties();
prop.load(new FileInputStream(
"C:\\Windows\\Sun\\Java\\Deployment\\deployment.properties"));
String Xmx = prop.getProperty("deployment.javaws.jre.0.args",
"This is Default");
if(Xmx!="This is Default")
{
System.setProperty("javaplugin.vm.options","\"Xmx\"");
}
long maxMemory = Runtime.getRuntime().maxMemory();
System.out.println("JVM maxMemory also equals to maximum heap size of JVM: "
+ maxMemory);
}
}
It should print the value of maxMemory around 96MB(for 2 gb RAM) when nothing specified in the deployment.properties AND 512MB when explicitly mentioning the deployment.javaws.jre.0.args=-Xmx512m.But in both case i am getting the result 259522560
The JVM memory parameters for a Hotspot Java implementation can only be set via the command line options when the JVM is launched / started. Setting them in the system properties either before or after the JVM is launched will have no effect.
What you are trying to do simply won't work.
By the time any Java code is able to run, it is too late to change the heap size settings. It is the same whether you run your code using the java command, using web start, using an applet runner, using an embedded JVM in a browser ... or any other means.
What is the simplest way to call a program from with a piece of Java code? (The program I want to run is aiSee and it can be run from command line or from Windows GUI; and I am on Vista but the code will also be run on Linux systems).
Take a look at Process and Runtime classes. Keep in mind that what you are trying to accomplish is probably not platform independent.
Here is a little piece of code that might be helpful:
public class YourClass
{
public static void main(String args[])
throws Exception
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("name_of_your_application.exe");
int exitVal = proc.exitValue();
System.out.println("Process exitValue: " + exitVal);
}
}
One question in S.O. discussing similiar issues. Another one. And another one.
You can get a runtime instance using Runtime.getRuntime() and call the runtime's exec method, with the command to execute the program as an argument.
For example:
Runtime runTime = Runtime.getRuntime ();
Process proc = rt.exec("iSee.exe");
You can also capture the output of the program by using getting the InputStream from the process.
The difficulty you will run into is how to get the application to know the path. You may want to use an xml or config file, but if you use this link, it should explain how to run a file:
http://www.javacoffeebreak.com/faq/faq0030.html
You may also want to consider passing in some kind of argument to your program to facilitate finding the specific program you want to run.
This could be with command line arguments, properties files or system properties.