• _sam (unregistered)

    I didn't think I was a Java expert, but then I [discovered Smirnoff | read the comments from people who thought they were]...

    Good article, made me giggle.

  • fahadsadah (unregistered) in reply to ShatteredArm
    ShatteredArm:
    It's a static method. No instance needs to be created to call that method.

    What makes you think he knows that?

  • Jean-Marc (unregistered) in reply to DaveK

    Java doesn't reference count... but I get what you are saying.

  • Yardik (unregistered)

    Wow.. these comments explain exactly what happened in the code WTF, seemingly the world is full of people who think they know how java works but really have no clue.

    If you don't know you are right, why would you open your mouth to spout bullsh!t? Especially in a community of people who should, at least, partially, know what is going on?

    How can you appreciate a good WTF if you don't recognize that you are perpetrating one by commenting on something you don't fundamentally understand?

    headdesk I have no clue.

  • Optical Aleutian (unregistered) in reply to Anonymous
    Anonymous:
    anonymous:
    I grow tired of this conversation. Summon the dancing girls!
    Alright! Let's dance!

    [image]

    Quick! Is she turning clockwise or counterclockwise?

  • runfaraway (unregistered) in reply to Anonymously Yours
    Anonymously Yours:
    I almost want to call this article a troll to get someone to say, "Java's the real WTF," and start a holy war...

    http://blog.aegisub.org/2008/12/if-programming-languages-were-religions.html

    Let's hope this code is not doing anything to the object's children...

  • Winston Chang (unregistered)

    Java method params are pass-by-value. In the case of object parameters, the reference is passed by value. It's a source of much confusion, as many people would call it "pass-by-reference", which is in a sense true, as the object is not copied, but the reference to the object is, so it's still pass-by-value. So in the case of the WTF, the method is setting a copy of the reference to null, while the original reference passed in is unaffected. That's why it does nothing.

  • (cs) in reply to pcooper
    pcooper:
    Maybe the coder was used to VB, where parameters are sent ByRef by default?
    That was changed 10 years ago. If you're going to pick on VB, at least get it right.
  • Chaos215bar2 (unregistered)

    TRWTF here is definitely the number of commenters who think this helps the garbage collector, deallocates the object, or does anything other than wasting CPU cycles and memory. Seriously, this is really basic Java here.

  • hmcclungiii (unregistered)
    One can hope, but I have seen people make a class with all methods static and then create instance of this class and call the static methods from the instance variable.
    And the award for stupidest bullsh*t comment goes to ...
  • (cs)

    TRWTF is that the Destruction class isn't final.

  • (cs) in reply to Jim
    Jim:
    Steve W:
    I'm not a Java guru (despite having used it extensively) so I'll say what I *think* is going wrong here.

    First of all, he's obviously instantiated a class whose sole purpose is to delete other objects. If this isn't a singleton then it will be taking up a lot of memory if he's instantiating a new instance every time.

    It's unlikely they are instantiating a new class since the method itself is static.
    I think he meant "instantiating a class" in the sense of "creating a new class", rather than "creating an object" of that class. I may be wrong though.
  • (cs)

    This sums up 25% of the comments today and fulfills the dancing girl request (kind of).

    [image]
  • (cs) in reply to Lunkwill
    Lunkwill:
    anonymous:
    I grow tired of this conversation. Summon the dancing girls!
    s/dancing/Irish/

    s/Irish/dancing Irish

  • Centurion (unregistered) in reply to Goo
    Goo:
    It'd not surprise me if this came from the kind of place that reboots their application server once or twice a day to keep the memory footprint at bay.
    Ooh, I used to work there! Seriously. We hired a guy whose sole job was to go from one webserver to the next, rebooting them, and incidentally killing the shopping carts of whoever was on at the time.

    No, we didn't want to automatically reboot them all at the same time. That would cause an outage!

  • Clock (unregistered) in reply to Optical Aleutian
    Optical Aleutian:
    Quick! Is she turning clockwise or counterclockwise?
    Yes.
  • (cs) in reply to Centurion
    Centurion:
    We didn't want to automatically reboot them all at the same time. That would cause an outage!

    Too bad nobody thought of automatically rebooting them all at different times.

  • ParkinT (unregistered)

    Setting a referenced object to null (aka NOTHING) inside a method (aka SUBroutine) has a very "VB-esque" flavor to it.

    DIM Object Object = ME Object = NOTHING

    I Object 2 VB

  • //Rumen (unregistered) in reply to pcooper

    In VB parameters are sent ByVal by default. :P

    And just to troll it up a little:

    "Java is TRWTF here"

  • EngleBart (unregistered)

    The comment + code truly makes the WTF.

    For CSODs like this, a mandatory example of how it was called needs to be included to prevent speculation on how it was called and most likely provide further WTFs. Of course, the worst example should be used!

    I could see using a marker method like this if I was coding something in Java that I knew would be ported to C++. (Probably a lot safer than trying to code in C++ and then port to Java) Since this sample was dealing with Java EJBs, I don't think we can give the author the benefit of the doubt.

    Now for the Java 101 lecture...

    Java object references are really pointers. If you understand how pointers work from C, C++, or assembly then you understand how Java object references work.

    Java severely limits the pointer/reference though. There is no pointer arithmetic. All objects are allocated in the heap, never on the stack. Unlike C/C++, you can NEVER assign an arbitrary value to the reference nor access its contents. A new Object from the heap, another pointer of the same type (copy the value), or null may be assigned to an object pointer/reference. That is about it.

    Since Java passes ALL parameters, both primitives and object references, by value (another name for pass by copy), the unknowable "pointer" value is copied on the stack creating a duplicate reference to the same object. As the caller of the function, you know that no one will ever mess with your "pointers", but the callee can mess with the Object that lives at the address of the pointer. This is the cause of many bugs in java. Some other code changes a value that you thought they couldn't! Alas, there is no const Object concept like C++. Many of the Java primitive types are immutable which is as close to a C++ const Object as I have seen.

    Garbage collection(gc) is an implementation specific detail, don't count on knowing how it actually works. Most JVMs support different algorithms for gc to allow you to tune it for different scenarios. (GUI vs. server backend vs. a batch program that exits and can dump the whole memory footprint quickly)

    In some scenarios, setting a null could be necessary to ensure garbage collection, but this is rare. Stack frames are a better solution in many cases.

    Unless you have taken the time to disassemble Java byte code, don't try to guess what you think is happening. Of course, as someone else pointed out, a lot of the TRWTFs appear in the comments.

    One guy that I used to work with started "optimizing" tons of code by changing the scope of variable declarations. Aside from introducing bugs, the only thing his optimization did was to change the order of 2 variables on the stack frame. He had to revert all of his code.

  • Mo (unregistered) in reply to javacoder
    javacoder:
    it allow the object to be garbage collected.... it is still a WTF because a one liner should be done by the caller

    Yeah, well, you know, that's just, like, your opinion, man.

  • Squire (unregistered)

    This is totally a WTF!

    The programmer is obviously an idiot, doing something so pointless and wasteful.

    public class Destruction {
        public static void delete(Object object){
            if (object != null) {
                object = null;
            }
        }
    }
    

    There, I fixed it.

    </sarcasm>
  • ClutchDude (unregistered)

    This might be borderline insulting to some, but here's a fun example for those who aren't quite getting the idea of how Java references work and why this code is a really big wtf.

    It also shows what Englebert talked about in regards to bug creation where member objects are messed with by methods that modify the object.

    package main;
    public class MainTest {
    	public String b=""; 
    	public static void main(String... args) {
    		MainTest a = new MainTest();
    		Destroy.destroy(a); 
    		if(a==null)
    			System.out.println("The a reference is null!"); 
    		else 
    			System.out.println("The a reference isn't null!");
    		if(a.b==null)
    			System.out.println("The b reference is null!"); 
    		else 
    			System.out.println("The b reference isn't null!");
    	
    	}
    	static class Destroy 
    	{
    		public static void destroy(Object o)
    		{
    			((MainTest) o).b=null; 
    			o = null;
    		}
    	}
    }
    
  • (cs) in reply to Anonymously Yours
    Anonymously Yours:
    I almost want to call this article a troll to get someone to say, "Java's the real WTF," and start a holy war...
    You need disagreement to have a war.
  • Swedish tard (unregistered) in reply to Optical Aleutian
    Optical Aleutian:
    Anonymous:
    anonymous:
    I grow tired of this conversation. Summon the dancing girls!
    Alright! Let's dance!

    [image]

    Quick! Is she turning clockwise or counterclockwise?

    Yes.

  • OutlawProgrammer (unregistered) in reply to Medinoc
    Medinoc:
    And if the programmer relies on this function, it's probable that the original object reference will never be set to null (and so, the object never deleted).

    I think this is the winner. When writing my initial comment, I wondered why the story ended with something like: "this was only one of the sources of memory leaks," when, clearly, no memory is either allocated nor freed. I can only assume that the author of the Destruction class also wrote a whole bunch of code that looks like this:

    final Map cache = new HashMap();
    
    Object get(String key)
    {
        Object value = cache.get(key);
        if(value == null)
        {
            value = datasource.get(key);
            cache.put(key, value);
        }
        return value;
    }
    
    Object remove(String key)
    {
        Object cached = cache.get(key);
        if(cached != null)
            Destruction.destroy(cached); // memory leak!
    }
    
  • I know java (unregistered) in reply to nobody
    nobody:
    agreed.

    you guys call yourselves coders? rule 1. stfu if you don't know and don't try to pull it out of your ass. rule 2. it's not pass by value. go to rule 1.

    Hmmm, pass by reference, pass by value. In Java there are two kinds of type: primitive types and reference types. There are, therefore two kinds of value: primitive values and reference values. Calls to methods are by value, the arguments being either primitive values or reference values.

    If you are unclear on this take a look at the JLS Edition 3, section 4.1 (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html). If you can't understand what it says there then please fuck off.

    Don't persist myths like Java is pass by reference. It's misunderstandings like that that lead to code of the calibre shown in the original post.

    If you think Java is pass by reference then could you write a simple swap function?

  • KMG (unregistered) in reply to Xyro

    Yes! Absolutely! I do indeed concur! Wholeheartedly!

  • (cs) in reply to I know java
    I know java:
    nobody:
    agreed.

    you guys call yourselves coders? rule 1. stfu if you don't know and don't try to pull it out of your ass. rule 2. it's not pass by value. go to rule 1.

    Hmmm, pass by reference, pass by value. In Java there are two kinds of type: primitive types and reference types. There are, therefore two kinds of value: primitive values and reference values. Calls to methods are by value, the arguments being either primitive values or reference values.

    If you are unclear on this take a look at the JLS Edition 3, section 4.1 (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html). If you can't understand what it says there then please fuck off.

    Don't persist myths like Java is pass by reference. It's misunderstandings like that that lead to code of the calibre shown in the original post.

    If you think Java is pass by reference then could you write a simple swap function?

    //Assumption a[] and b[] have one element each
    void swap(Object a[], Object b[])
    {
       object temp = a[0].clone();
       a[0] = b[0].clone();
       b[0] = temp;
        
    }
    
  • Me (unregistered) in reply to javacoder
    javacoder:
    it allow the object to be garbage collected.... it is still a WTF because a one liner should be done by the caller

    BaBow...Try Again....

  • Welcor (unregistered) in reply to frits
    frits:
    //Assumption a[] and b[] have one element each
    void swap(Object a[], Object b[])
    {
       object temp = a[0].clone();
       a[0] = b[0].clone();
       b[0] = temp;
    

    }

    I fail to see how this is better than

    //Assumption a[] and b[] have one element each
    void swap(Object a[], Object b[])
    {
       object temp = a[0];
       a[0] = b[0];
       b[0] = temp;
    }
    

    What did those clone() calls do?

  • Welcor (unregistered) in reply to Welcor

    Oh, and by the way - this isn't passing by reference. This is passing a copy of the reference to two array objects, and then manipulating those objects.

  • Caffeine (unregistered)

    I'm not a Java programmer, but unless the language completely redefines how object programming languages work:

    • Person A tells Person B where the memory party is.
    • Person B is a goldfish or Dory from Nemo and immediately forgets where the party is.
    • Person A doesn't have some kind of freaky Vulcan mind-meld with Person A and still knows where the party is. Truth be told A is rather glad when Person B doesn't turn up because he always thought B was a bit of a tosser.

    Captcha Genitus: The first book of the Freudian Bible

  • (cs) in reply to javacoder
    javacoder:
    it allow the object to be garbage collected.... it is still a WTF because a one liner should be done by the caller

    The text in red is a WTF. Consider the following:

    Object lonelyTurd = new Object();
    Destructor.delete( lonelyTurd );
    // lonelyTurd is still referenciable
    // it ain't gonna get garbage collected

    A method's argument is only one of possibly many references to that object. Setting it to null does nothing.

    No, it doesn't allow the object referenced by lonelyTurd to get garbage collected.

    Once all references to an object become unreachable, then the object becomes eligible for garbage collection.

    Then it is moved to the "younger generation" region by a minor garbage collection. It is first placed in a section memory section called the "Eden", then to one "survivor" space, and then to another.

    Then, at a later time when it is deemed sufficiently old on the second "survivor" space, it is moved to the "tenured generation" memory space. Then ,when a "major" garbage collection executes, then and only then this object is finally garbage collected.

  • Fedaykin (unregistered) in reply to Steve W
    Steve W:
    I'm not a Java guru (despite having used it extensively) so I'll say what I *think* is going wrong here.

    First of all, he's obviously instantiated a class whose sole purpose is to delete other objects. If this isn't a singleton then it will be taking up a lot of memory if he's instantiating a new instance every time.

    Secondly, setting it to null doesn't help. Best let the garbage collector do things on its own. I can't remember Java's semantics for parameters but I think it's a local copy of the object which is being set to null and not the original memory reference.

    \

    A.) It's a static method, there will only ever be one instance (per class loader) of that method.

    B.) Java is pseudo pass-by-reference. A copy of the reference is made and handed to the called method. However, the heap-allocated object is never copied.

  • Dave (unregistered)

    Yeah.... seems to be written by one of those people who chose a managed environment so the 'don't have to worry about memory management' =D

    Ranks right up beside the code i see from one of our C# developers on a regular basis. It looks something like:

    if (null == myValueType) Throw new WtfTheyveChangedTheDotNetFrameworkException();

  • (cs) in reply to Swedish tard
    Swedish tard:
    Optical Aleutian:
    Anonymous:
    anonymous:
    I grow tired of this conversation. Summon the dancing girls!
    Alright! Let's dance!

    [image]

    Quick! Is she turning clockwise or counterclockwise?

    Yes.

    Both, among other things, depending on where exactly you are looking at her from. Also, at any given point in time progression she is also not moving, which leads to the impression that she is actually just standing still. If I had to stand still with my leg out like that for 2 seconds I'd faint...

    :D

  • (cs) in reply to nobody
    nobody:
    agreed.

    you guys call yourselves coders? rule 1. stfu if you don't know and don't try to pull it out of your ass. rule 2. it's not pass by value. go to rule 1.

    Everything is passed by value in Java, both primitives and Object pointers.

    From the JSL : http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#20448

    When the method or constructor is invoked (�15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared Type, before execution of the body of the method or constructor. The Identifier that appears in the DeclaratorId may be used as a simple name in the body of the method or constructor to refer to the formal parameter.

    What that also implies however, and taking into consideration that there is no explicit pointer de-referencing in Java, every Java pointer is itself an immutable Object reference.

    And what does that mean in codespeak? That objects are passed by reference.

    The reference to the object is passed by value (the the value of the memory address it points to gets copied). That is the definition of passing by value.

    The object being referenced to, however, does not get copied or cloned. It is still referenced by the copy of the memory address value pointing to it. That is the definition of passing by reference.

    That is, in Java, Object pass-by-reference is implemented by enforcing a pass-by-value on the Object references themselves. A coder knows the difference.

  • Frank (unregistered) in reply to Dave
    Dave:
    if (null == myValueType) Throw new WtfTheyveChangedTheDotNetFrameworkException();
    Well, yeah! It should be:

    if (myValueType == null)

    for readability!

  • Tama (unregistered)

    I'm actually thinking that this would be a great interview question...

  • //Rumen (unregistered) in reply to nobody
    nobody:
    agreed.

    you guys call yourselves coders? rule 1. stfu if you don't know and don't try to pull it out of your ass. rule 2. it's not pass by value. go to rule 1.

    I thought rule '1' is 'You do NOT talk about fight club' ?

  • anon (unregistered)

    this code is ridiculous, the class should have a private constructor to prevent inexpierienced programmers instantiating it.

  • (cs) in reply to luis.espinal

    [quote user="luis.espinal"][quote user="nobody"]agreed.

    The object being referenced to, however, does not get copied or cloned. It is still referenced by the copy of the memory address value pointing to it. That is the definition of passing by reference. [/quote]

    Kinda true but you forget one thing. The object is newer passed to the function. Think about it. The object is newer passed to the function. A reference to the object is passed to the function, so talking about whatever the object is passed by value or reference does not make sense because the object is newer passed to the function.

    And

  • (cs)
    private static List<Object> trashcan = new ArrayList<Object>();
    
    private static void Destroy(Object object) {
      trashcan.add(object);
      object = null;
      System.out.println("" + trashcan.size() + " objects have been destroyed.");
    };
  • (cs) in reply to tiller
    tiller:
    The object is newer passed to the function. Think about it. The object is newer passed to the function. A reference to the object is passed to the function, so talking about whatever the object is passed by value or reference does not make sense because the object is newer passed to the function.
    “Newer”??

    You keep using that word. I do not think it means what you think it means.

    (What does the age of the object have to do with anything?)

  • (cs) in reply to luis.espinal
    luis.espinal:
    That is, in Java, Object pass-by-reference is implemented by enforcing a pass-by-value on the Object references themselves. A coder knows the difference.
    Remember, a C++ coder doesn't understand the difference.
  • Jinks (unregistered)

    variables and pointers. concepts which elude many.

  • (cs) in reply to md5sum
    md5sum:
    at any given point in time progression she is also not moving

    Zeno's arrow paradox...

    http://en.wikipedia.org/wiki/Zeno%27s_paradoxes

  • SomeJavaGuy (unregistered) in reply to luis.espinal
    luis.espinal:

    Once all references to an object become unreachable, then the object becomes eligible for garbage collection.

    Then it is moved to the "younger generation" region by a minor garbage collection. It is first placed in a section memory section called the "Eden", then to one "survivor" space, and then to another.

    Then, at a later time when it is deemed sufficiently old on the second "survivor" space, it is moved to the "tenured generation" memory space. Then ,when a "major" garbage collection executes, then and only then this object is finally garbage collected.

    I feel compelled to point out that as soon as an object becomes eligible for collection, it will be collected by the next collection that affects the region it's in. If it becomes eligible in the Eden space (as many objects do), it won't make it to the survivor space, and similarly for the survivor to survivor/tenured spaces. Minor collections affect the Eden and survivor spaces, major collections affect Eden, survivor, and tenured spaces.

    What you described would defeat the entire purpose of generational garbage collection, which is to take advantage of the relative frequencies of different object lifespans (the vast majority of which live either very briefly or forever).

  • Bonghit (unregistered)

    Dont know java, but in .Net land we have object.Finalize() method which should force a garbage collection on object if i remember right.

    suscipit - moo

Leave a comment on “Java Destruction”

Log In or post as a guest

Replying to comment #:

« Return to Article