What is an easy way to cause a heap overflow in Java? I need to test how some external code responds when memory goes away.
Simpler than adding elements to an array list imho is to just cut out the middleman:
public static void main(String[] args) {
int[] a = new int[Integer.MAX_VALUE];
}
Well theoretically not guaranteed to lead to a OoME but since the arraylist uses an array internally itself, the same limitations apply to the other solutions as well..
If all you want is an OutOfMemoryError
throw new OutOfMemoryError();
note: int[] a = new int[Integer.MAX_VALUE]; will only throw an OOME if you have less than 8 GB of heap free.
ArrayList<String> heapme = new ArrayList<String>();
while ( true ) {
heapme.add( "I WANT TO HEAP MY VIRTUAL MACHINE TO DEATH PLZ!!! K THNX BIE!!!!" );
}
Create an ArrayList, and add objects to it:
private static final List<String> list = new ArrayList<String>();
// ...
while(true) list.add("Hello World");
and, BTW, it's called a Memory Leak. OutOfMemoryError will be thrown.
Moreover, if you want a StackOverflow, you can do it with an infinite recursive method:
public void Foo(){Foo();}
StackOverflowError will be thrown.
Related
How can I find the number of live objects on the heap in Java program?
jmap is the standard java utility that you can use to capture heap dumps and statistics. I can't say what protocol is used by jmap to connect to the JVM to get this info, and it's not clear if this information is available to a program running in the JVM directly (though I'm sure the program can query it's JVM through some socket to get this information).
JVM TI is a tool interface used by C code, and it has pretty much full access to the goings on of the JVM, but it is C code and not directly available by the JVM. You could probably write a C lib and then interface with it, but there's nothing out of the box.
There are several JMX MBeans, but I don't think any of them provide an actual object count. You can get memory statistics from these though (these are what JConsole uses). Check out the java.lang.management classes.
If you want some fast (easy to implement, not necessarily a quick result as a jmap takes some time), I'd fork off a run of jmap, and simply read the resulting file.
The simplest way is to use jmap tool. If you will print objects histogram at the end you'll see total number of instances and also accumulated size of all objects:
jmap -histo <PID> will print whole objects with number of instances and size. The last line will contain total number
Total 2802946 174459656
Second column is total instances count, and last is total bytes.
Use jvisualvm, and do a memory sample. It will show the number of classes and instances:
There is a hack you can try:
create your own java.lang.Object (copy the original source)
count the created objects in the constructor (not called for arrays)
add the path to your classfile to the boot classpath
see this (old) article for a sample.
Probably there are better ways to do it using JPDA or JMX, but I've not found how...
As far as I know, you cannot. You can, however, get the amount of memory used for the program:
Runtime rt = Runtime.getRuntime();
System.out.println("Used: " + (rt.totalMemory() - rt.freeMemory());
System.out.println("Free: " + rt.freeMemory());
System.out.println("Total: " + rt.totalMemory());
If all your objects are created using some kind of Factory class you can find number of objects in the heap. Even then you have to have something in the finalize() method. Of course, this cannot be done for all objects, e.g. the jdk library classes cannot be modified. But if you want to find number of instances of a particular class you have created you can potentially find that.
For debugging, you can use a profiler (like YourKit, a commercial java profiler). You'll find both open source and commercial variants of java profilers.
For integration with your code, you might look at using "Aspect Oriented Programming" technique. AOP frameworks (e.g. AspectWerkz) let you change the class files at class load time. This will let you modify constructors to register objects to your "all-my-runtime-objects-framework".
public class NumOfObjects {
static int count=0;
{
count++;
}
public static void main(String[] args)
{
NumOfObjects no1=new NumOfObjects();
System.out.println("no1:" + count);//1
NumOfObjects no2=new NumOfObjects();
System.out.println("no2:"+ count); //2
for (int i=0; i<10;i++)
{
NumOfObjects noi=new NumOfObjects();
}
System.out.println("Total objects:"+count);// 12
}
}
public class ObjectCount
{
static int i;
ObjectCount()
{
System.out.println(++i);
}
public static void main(String args[])
{
ObjectCount oc = new ObjectCount();
ObjectCount od = new ObjectCount();
ObjectCount oe = new ObjectCount();
ObjectCount of = new ObjectCount();
ObjectCount og = new ObjectCount();
}
}
class Test1
{
static int count=0;
public Test1()
{
count++;
System.out.println("Total Objects"+" "+count);
}
}
public class CountTotalNumberOfObjects
{
public static void main(String[] args)
{
Test1 t = new Test1();
Test1 t1 = new Test1();
Test1 t3 = new Test1();
Test1 t11 = new Test1();
Test1 t111 = new Test1();
Test1 t13 = new Test1();
}
}
I have a question about how GC works in Java.
Consider the following code:
class C1 {
ArrayList<int> myList = new ArrayList<int>();
public void setList(ArrayList<int> l) {
myList = l;
}
}
func(C1 C) {
ArrayList<int> l1 = new ArrayList<int>();
l1.add(1);
C.setList(l1);
}
main() {
C1 C = new C1();
func(C);
...
}
my question is:
does GC releases 'l1' after func() returns or not?
No, it doesn't, because there's a root reference (stack variable C) which has a strong reference (myList), to the new ArrayList. After main() returns, then the C1 and the ArrayList are collectible, because the root reference disappears.
There is actually an optimization that HotSpot's JIT does, which is detecting the point at which a local var will no longer be accessed and clearing it at that moment. So the full answer to your question is "it might, but there is no guarantee". Recently I played with some code and measured the memory taken by a large array. Until I actually inserted array.hashCode() at te end of the method, I observed it was being released earlier.
Given this C++ Code:
void LoadData(char** myVar)
{
std:: string str("[Really Long String Here]");
unsigned int size = str.length() + 1;
*myVar = new char[size];
strncpy(*myVar, str.c_str(), size);
}
And this JNA Java:
Pointer myVar = new Memory(Pointer.SIZE);
this.Lib.LoadData(myVar);
this.someVar = myVar.getPointer(0).getString(0);
I'm having memory leaks, as I understand it, getPointer(0) should create a pointer object that should be released on finalize(), but it seems to not be.
Am I missing something? This seems up to spec... and I can run the function above with no leaks in C++ fine.
I call the Java code in a loop to test the leak, I've tried putting in pauses, and manually calling the GC, also it'll bloat to gigabytes rather quickly this way.
I've been banging my head against this for a few days now and it sucks to get hung up on something so trivial as attempting to free memory.As far as I can tell I can only manually free memory in Java if I have the address, but I can't see how I'd get that.
Edit:
Nevermind, I don't even think there is a way to do manually free through JNA without extending it...
Add this function to the C++ library...
void FreeData(char** myVar)
{
delete [] *myVar;
}
And then make this the JNA code
Pointer myVar = new Memory(Pointer.SIZE);
this.Lib.LoadData(myVar);
this.someVar = myVar.getPointer(0).getString(0);
this.Lib.FreeData(myVar);
This way you allocate and delete the memory in C++.
Allocate in the caller, not the callee.
For example:
int LoadData(char* buf, int maxlen) {
std:: string str("[Really Long String Here]");
strncpy(buf, str.c_str(), maxlen);
if (str.length() < maxlen)
return str.length();
return maxlen;
}
Then when you call from Java, pass in a byte[] of the appropriate size. Note that this implementation is potentially very inefficient, but the idea is that you don't generally want to be allocating memory in one context and deallocating it in another.
Instead of
myVar = new char[size]
use
*myVar = malloc(size);
strncpy(*myVar, str.c_str(), size);
Arrays need to be deleted like:
delete [] *myVar;
JNA prolly doesn't know to do that.
Is it (performance-wise) better to use Arrays or HashMaps when the indexes of the Array are known? Keep in mind that the 'objects array/map' in the example is just an example, in my real project it is generated by another class so I cant use individual variables.
ArrayExample:
SomeObject[] objects = new SomeObject[2];
objects[0] = new SomeObject("Obj1");
objects[1] = new SomeObject("Obj2");
void doSomethingToObject(String Identifier){
SomeObject object;
if(Identifier.equals("Obj1")){
object=objects[0];
}else if(){
object=objects[1];
}
//do stuff
}
HashMapExample:
HashMap objects = HashMap();
objects.put("Obj1",new SomeObject());
objects.put("Obj2",new SomeObject());
void doSomethingToObject(String Identifier){
SomeObject object = (SomeObject) objects.get(Identifier);
//do stuff
}
The HashMap one looks much much better but I really need performance on this so that has priority.
EDIT: Well Array's it is then, suggestions are still welcome
EDIT: I forgot to mention, the size of the Array/HashMap is always the same (6)
EDIT: It appears that HashMaps are faster
Array: 128ms
Hash: 103ms
When using less cycles the HashMaps was even twice as fast
test code:
import java.util.HashMap;
import java.util.Random;
public class Optimizationsest {
private static Random r = new Random();
private static HashMap<String,SomeObject> hm = new HashMap<String,SomeObject>();
private static SomeObject[] o = new SomeObject[6];
private static String[] Indentifiers = {"Obj1","Obj2","Obj3","Obj4","Obj5","Obj6"};
private static int t = 1000000;
public static void main(String[] args){
CreateHash();
CreateArray();
long loopTime = ProcessArray();
long hashTime = ProcessHash();
System.out.println("Array: " + loopTime + "ms");
System.out.println("Hash: " + hashTime + "ms");
}
public static void CreateHash(){
for(int i=0; i <= 5; i++){
hm.put("Obj"+(i+1), new SomeObject());
}
}
public static void CreateArray(){
for(int i=0; i <= 5; i++){
o[i]=new SomeObject();
}
}
public static long ProcessArray(){
StopWatch sw = new StopWatch();
sw.start();
for(int i = 1;i<=t;i++){
checkArray(Indentifiers[r.nextInt(6)]);
}
sw.stop();
return sw.getElapsedTime();
}
private static void checkArray(String Identifier) {
SomeObject object;
if(Identifier.equals("Obj1")){
object=o[0];
}else if(Identifier.equals("Obj2")){
object=o[1];
}else if(Identifier.equals("Obj3")){
object=o[2];
}else if(Identifier.equals("Obj4")){
object=o[3];
}else if(Identifier.equals("Obj5")){
object=o[4];
}else if(Identifier.equals("Obj6")){
object=o[5];
}else{
object = new SomeObject();
}
object.kill();
}
public static long ProcessHash(){
StopWatch sw = new StopWatch();
sw.start();
for(int i = 1;i<=t;i++){
checkHash(Indentifiers[r.nextInt(6)]);
}
sw.stop();
return sw.getElapsedTime();
}
private static void checkHash(String Identifier) {
SomeObject object = (SomeObject) hm.get(Identifier);
object.kill();
}
}
HashMap uses an array underneath so it can never be faster than using an array correctly.
Random.nextInt() is many times slower than what you are testing, even using array to test an array is going to bias your results.
The reason your array benchmark is so slow is due to the equals comparisons, not the array access itself.
HashTable is usually much slower than HashMap because it does much the same thing but is also synchronized.
A common problem with micro-benchmarks is the JIT which is very good at removing code which doesn't do anything. If you are not careful you will only be testing whether you have confused the JIT enough that it cannot workout your code doesn't do anything.
This is one of the reason you can write micro-benchmarks which out perform C++ systems. This is because Java is a simpler language and easier to reason about and thus detect code which does nothing useful. This can lead to tests which show that Java does "nothing useful" much faster than C++ ;)
arrays when the indexes are know are faster (HashMap uses an array of linked lists behind the scenes which adds a bit of overhead above the array accesses not to mention the hashing operations that need to be done)
and FYI HashMap<String,SomeObject> objects = HashMap<String,SomeObject>(); makes it so you won't have to cast
For the example shown, HashTable wins, I believe. The problem with the array approach is that it doesn't scale. I imagine you want to have more than two entries in the table, and the condition branch tree in doSomethingToObject will quickly get unwieldly and slow.
Logically, HashMap is definitely a fit in your case. From performance standpoint is also wins since in case of arrays you will need to do number of string comparisons (in your algorithm) while in HashMap you just use a hash code if load factor is not too high. Both array and HashMap will need to be resized if you add many elements, but in case of HashMap you will need to also redistribute elements. In this use case HashMap loses.
Arrays will usually be faster than Collections classes.
PS. You mentioned HashTable in your post. HashTable has even worse performance thatn HashMap. I assume your mention of HashTable was a typo
"The HashTable one looks much much
better "
The example is strange. The key problem is whether your data is dynamic. If it is, you could not write you program that way (as in the array case). In order words, comparing between your array and hash implementation is not fair. The hash implementation works for dynamic data, but the array implementation does not.
If you only have static data (6 fixed objects), array or hash just work as data holder. You could even define static objects.
How can I find the number of live objects on the heap in Java program?
jmap is the standard java utility that you can use to capture heap dumps and statistics. I can't say what protocol is used by jmap to connect to the JVM to get this info, and it's not clear if this information is available to a program running in the JVM directly (though I'm sure the program can query it's JVM through some socket to get this information).
JVM TI is a tool interface used by C code, and it has pretty much full access to the goings on of the JVM, but it is C code and not directly available by the JVM. You could probably write a C lib and then interface with it, but there's nothing out of the box.
There are several JMX MBeans, but I don't think any of them provide an actual object count. You can get memory statistics from these though (these are what JConsole uses). Check out the java.lang.management classes.
If you want some fast (easy to implement, not necessarily a quick result as a jmap takes some time), I'd fork off a run of jmap, and simply read the resulting file.
The simplest way is to use jmap tool. If you will print objects histogram at the end you'll see total number of instances and also accumulated size of all objects:
jmap -histo <PID> will print whole objects with number of instances and size. The last line will contain total number
Total 2802946 174459656
Second column is total instances count, and last is total bytes.
Use jvisualvm, and do a memory sample. It will show the number of classes and instances:
There is a hack you can try:
create your own java.lang.Object (copy the original source)
count the created objects in the constructor (not called for arrays)
add the path to your classfile to the boot classpath
see this (old) article for a sample.
Probably there are better ways to do it using JPDA or JMX, but I've not found how...
As far as I know, you cannot. You can, however, get the amount of memory used for the program:
Runtime rt = Runtime.getRuntime();
System.out.println("Used: " + (rt.totalMemory() - rt.freeMemory());
System.out.println("Free: " + rt.freeMemory());
System.out.println("Total: " + rt.totalMemory());
If all your objects are created using some kind of Factory class you can find number of objects in the heap. Even then you have to have something in the finalize() method. Of course, this cannot be done for all objects, e.g. the jdk library classes cannot be modified. But if you want to find number of instances of a particular class you have created you can potentially find that.
For debugging, you can use a profiler (like YourKit, a commercial java profiler). You'll find both open source and commercial variants of java profilers.
For integration with your code, you might look at using "Aspect Oriented Programming" technique. AOP frameworks (e.g. AspectWerkz) let you change the class files at class load time. This will let you modify constructors to register objects to your "all-my-runtime-objects-framework".
public class NumOfObjects {
static int count=0;
{
count++;
}
public static void main(String[] args)
{
NumOfObjects no1=new NumOfObjects();
System.out.println("no1:" + count);//1
NumOfObjects no2=new NumOfObjects();
System.out.println("no2:"+ count); //2
for (int i=0; i<10;i++)
{
NumOfObjects noi=new NumOfObjects();
}
System.out.println("Total objects:"+count);// 12
}
}
public class ObjectCount
{
static int i;
ObjectCount()
{
System.out.println(++i);
}
public static void main(String args[])
{
ObjectCount oc = new ObjectCount();
ObjectCount od = new ObjectCount();
ObjectCount oe = new ObjectCount();
ObjectCount of = new ObjectCount();
ObjectCount og = new ObjectCount();
}
}
class Test1
{
static int count=0;
public Test1()
{
count++;
System.out.println("Total Objects"+" "+count);
}
}
public class CountTotalNumberOfObjects
{
public static void main(String[] args)
{
Test1 t = new Test1();
Test1 t1 = new Test1();
Test1 t3 = new Test1();
Test1 t11 = new Test1();
Test1 t111 = new Test1();
Test1 t13 = new Test1();
}
}