4 Benefits of Implementing DevOps

DevOps is a tech industry buzzword that refers to the collaboration of a software development team and operations teams within a company. The results are a Development + Operations team, a DevOps team

While it’s a buzzword, it also represents a new shift left standard that’s starting to take hold in the software development industry. In the interest of creating better software products, maintaining a manageable schedule, and upholding a higher reputation, DevOps teams are taking a step in the right direction for any company that normally separates these two functions. 

Traditional SDLC 

With a more traditional software development life cycle, products first go through coding in large blocks within the development team. Once development is satisfied that a software product does what it should and works well in their testing, they move it over to operations for additional testing and eventual deployment and management. 

Typically, developers work with large blocks of code at a time. This makes adjustments, bug fixes, updates, and small changes difficult and a little clunky. The process can take a lot of time, especially if operations has a strict schedule for turning over work, editing, and deploying. Overall, you could be looking at months between when a software is coded and when it’s refined for deployment. 

DevOps changes up this process by combining development teams with operations and rearranging the entire process. Instead of large chunks of code being handed over to operations all at once, little bits and individual parts can be immediately turned in, reviewed, tested, and deployed. It makes the software development process seamless and more convenient for all involved parties. It may not be a perfect solution for developers, but it smooths out a lot of the wrinkles in the SDLC. 

You can expect a few specific outcomes from using a DevOps approach. These include: 

1. Improved Time to Market 

By using a DevOps strategy and streamlining the process, you can get software products to market more quickly and produce new products, updates, and software. Keeping the development and operations team working together closely makes feedback faster and helps developers make the necessary changes in a reasonable timeframe. 

2. Higher Levels of Automation 

DevOps teams usually automate a lot of the central processes to speed up the entire development cycle. Automation takes the manual labor out of many time-consuming and repetitive tasks, freeing developer’s time to start working on additional projects. 

3. More Responsive to Business Needs 

Developers in the standard SDLC are not very connected to the end results when it is produced and distributed. By the time the software reaches the public, it has been a long time since the developers have played a significant role in its creation. They’re not as familiar with the code anymore, and tend to be less connected to the needs of people using the software. 

What works in the development environment doesn’t always work properly in the production environment. When development and operations are completely out of sync with each other, issues don’t get addressed on time and communication often breaks down. The team in charge of development needs to be involved with the team in charge of testing, deployment, and maintenance. 

DevOps gives developers the chance to respond to market demands and business needs in a shorter time. You as the developer will be more involved with the process of both creating, deploying, and monitoring performance in real-time. You get the opportunity to respond quickly when an update, bug fix, or change is necessary. 

In an effort to increase response times, DevOps teams often implement APM tools, such as Stackify Retrace, for their alerts and notifications.  Combining the reactive monitoring capabilities of alerts and notification with the preventative measures of code level profiling, Retrace allows you to improve the performance of your application.

4. Increased Collaboration 

Collaboration between different working teams is beneficial for an organization and the individual team members. In most instances, collaboration brings in new ideas and perspectives while creating a more harmonious working environment for both teams. 

When development and operation teams are collaborating, dev teams tend to have better access to feedback from the deployment and management of a software they produced. In the traditional SDLC process, this feedback is limited and tends to come from end users, if it’s received at all. It can be difficult to keep everything running smoothly under these circumstances. A lot of time and money are wasted through inefficiencies in working teams. 


With the software development industry moving away from the traditional SDLC and towards a collaborative DevOps approach, development teams are benefiting from a more efficient process.  Teams now have improved time to market, higher levels of automation, more responsive to business needs, and increased collaboration.


Equality in Java: Operators, Methods, and What to Use When

Equality is an essential concept when programming, not only in Java but in pretty much all programming languages. After all, much of what we do when writing code has to do with comparing values and then making decisions based on the results of such comparisons.

Unfortunately, dealing with equality can often be tricky, despite being such a vital part of everyday coding. Equality in Java, specifically, can be quite confusing, for beginners and more experienced developers alike. That’s probably due to the fact that, in Java, there are several ways of handling equality, which can become overwhelming.

Today’s post has the goal of making this whole situation less confusing and less overwhelming. By the end of the post, you’ll have learned about the different ways to deal with equality in Java, and when to use which of them. We’ll also cover some best practices you should adopt and some pitfalls you must be aware of. Let’s get started.

The == Operator

Let’s begin by covering the equality comparison with the == operator. We’ll first show a quick example, and then dive a little deeper, explaining important details you need to be aware of when using the operator.

Using the == Operator With Primitive Types

When you use the equality operator with primitive types, you’re just comparing their values. Take a look at the following examples:

 // comparing ints
    int x, y;
    x = 10;
    y = 15;
    System.out.println(x == y); // prints 'false'

    // comparing chars
    char a, b;
    a = 'n';
    b = 'n';
    System.out.println(a == b); // prints 'true'

    // comparing booleans
    boolean t, f;
    t = true;
    f = false;
    System.out.println(t == f); // prints 'false'

Using the == Operator With Object Types

When it comes to object types, the == operator is used to perform a referential equality comparison. What does that mean? It means that when you use the operator with object types, what you’re actually doing is testing whether the two variables have references that point to the same space in memory. Even if the objects referenced by the variables are identical in regards to their values, the results will still be false. This is somewhat unintuitive, and it can be a source of confusion—and bugs—especially for beginners. Let’s illustrate that with a code example. Suppose you have a Person class, like the one below:

 public class Person {
 private final String name;

 private final int age;

 public String getName() {
 return name;

 public int getAge() {
 return age;

 public Person(String name, int age) { = name;
 this.age = age;

Now, consider the following main method:

 public static void main(String[] args) {
     Person p = new Person("Alice", 20);
     Person p2 = new Person("Alice", 20);
     System.out.println(p == p2);

What do you think our little program will print when we run it? If your answer is false, then you’ve got it right. But why is that the case?

It has to do with references. When we initialize the p variable, we create a new instance of the Person class, which will live somewhere in the memory. The content of p is a reference (an “addressâ€) to the location where the object resides.

When we utilize the p2 variable, we create another instance of Person. However, this instance will live at a different location in memory, and it’s this location that gets assigned to the variable. When using the == operator to compare the variables, we’re actually comparing the references they store, which are obviously different, so we get false as a result.

When using the operator to compare object types, the arguments must be compatible. That means that you can compare arguments of the same type, but also of types that have a child/parent relationship. If the arguments aren’t of the same type neither extend from one another, and you’ll get a compiler error. An example would show this more clearly. Consider the excerpt of code below:

 public class Student extends Person {

    private final String school;

    public Student(String name, int age, String school) {
        super(name, age); = school;

    public String getSchool() {
        return school;

The example above features a new class, Student, that extends from the Person class shown in the first example. Now, take a look at the example below, that shows how we can compare instances of the two classes:

    Person p = new Person("Alice", 20);
    Person p1 = new Person("Alice", 20);
    Student s = new Student("Alice", 20, "Hogwarts");
    Student s1 = new Student("Alice", 20, "Hogwarts");
    Person p2 = s;

    System.out.println(p == p1); // prints 'false'
    System.out.println(p2 == s); // prints 'true'
    System.out.println(s == s1); // prints 'false'
    System.out.println(p == s1); // prints 'false'
    System.out.println(p == "test"); // compiler error

The first comparison returns false. Both arguments have the same type (Person). They point to objects which have the exact same values for their fields. But even though their values are equal, they’re not the same objects. They don’t share the same place in memory, and that’s what the operator is comparing.

The second comparison results in true. Here we’re comparing two variables that are of different, but compatible types, since Person is the parent of Student. The comparison returns true because both variables point to the same object.

The third comparison checks two variables of type Student. The variables point to objects that have the exact same values. Yet, the comparison returns false, since the objects don’t share the same reference.

Following next, we have a comparison between an instance of Person and an instance of Student. The types are compatible, but the result is false since the objects the variables point to aren’t the same.

Finally, we have a comparison between an instance of Person and a string. Since these types aren’t compatible, we get a compiler error.

Equality in Java Using the equals() Method

The second main way of performing an equality comparison in Java is by using the equals() method. How does this differ from the operator? To answer that question, let’s go back to our first example, but replacing the operator with the method. The Person class itself will remain the same, at least for now:

 public static void main(String[] args) {
    Person p = new Person("Alice", 20);
    Person p1 = new Person("Alice", 20);

If you run the code, you’ll see that it prints false, just like the first version. So, what’s the difference?

How Does the equals() Method Really Work

To understand why the previous example behaved the way it did, we must learn how the equals() method really works. We’ll do that by clarifying an oft-repeated—but sadly inaccurate—claim about the method. When somebody asks about the difference between == and equals(), it doesn’t take long for this answer to show up:

The == operator compares the references, while the equals() compare the values themselves.

The inaccurate part is the second half of the quote. You see, the method doesn’t necessarily compare its arguments by their values. It only compares what was asked of it to compare. What does that mean? It means that for a class to have a custom equality comparison, it must override the equals() method, providing its own implementation. Let’s do just that for the Person class:

    public boolean equals(Object obj) {
        if (obj == null) {
            return false;

        if (!Person.class.isAssignableFrom(obj.getClass())) {
            return false;

        Person other = (Person)obj;
        return && other.age == age;

The code above should be easy to follow. We first test whether the argument is null, in which case we return false. Then we check whether the argument’s class is compatible with Person. If it’s not, we also return false.

Finally, we cast the argument to Person and compare the values of its private fields with those from the instance’s fields, returning the result of the comparison. Now, if you go back and run the previous main example again, you’ll see that this time it prints true.

Long colorful lines of code on a computer screen

What If the Object Doesn’t Override equals()?

As we’ve just seen, it’s relatively easy to write a custom implementation of the equals() method. But what happens when a class doesn’t override it?

At first, it defaults to the implementation of the closest ancestral class which has overridden the method. But what if no ancestral class provided an implementation of the method? For instance, our Person class doesn’t even extend from anyone; from whom would it inherit the equals() implementation?

That’s not quite true, actually. In Java, every class has the Object class as a parent. And Object’s implementation of equals() defaults to ==. In other words: if neither your class nor its ancestors provide a custom implementation of the equals() method, you’ll end-up performing a reference comparison, perhaps inadvertently.

Equality in Java: A Few Best Practices and Pitfalls You Must Be Aware of

Before we part ways, let’s briefly offer a few tips on how to handle equality in Java, in the form of a brief list of best practices to adhere to and pitfalls to avoid.

First, don’t use == when comparing strings! That is unless you really want to do a comparison by references. This a very common mistake, and it can lead to annoying bugs. Actually, that applies not only to strings but to all object types.

Second, adhere to the principle of least astonishment when overriding the equals() method. That means that you should stick to widespread conventions, so your code doesn’t behave in an unexpected way that will alienate its users. For instance, you should always return false when comparing to null, the reasoning here being that, since null means nothing, it’s always going to be different than “somethingâ€, no matter what that something is.

Finally, always override hashCode() if you’re overriding equals(). If two objects are equal (by the equals() method), then they must have the same hash code. That will ensure that they can be used, for instance, as keys on a HashMap.

Java is one of the most popular programming languages ever, and that’s not an easy feat. Even after more than two decades, the language keeps being updated, making it easier to develop applications that are reliable, secure and easy to maintain.


In Java, as in any other language, equality is a crucial concept, but it can also be somewhat tricky to master. In today’s post we’ve covered how to deal with equality in Java using both the == operator and the equals() method. We’ve explained the difference between the two with code examples, and we’ve walked you through a list of best practices and potential problems to be aware of.

That was just the tip of the iceberg, though. There are much more that can be said and written about equality than would fit into a single blog post. Keep always reading and practicing to learn more about Java and programming in general. This blog always features articles on a variety of subjects, not only on Java, but also on other programming languages and tools, so remember to always check it out.

Additionally, make good use of the tools at your disposal. For instance, check out Retrace, which is the APM solution by Stackify that can help you boost your application performance and quality. Try it today.


How to Troubleshoot IIS Worker Process (w3wp) High CPU Usage

Having IIS performance problems? Do you have w3wp.exe high CPU usage? How do you troubleshoot IIS Worker Process High CPU usage?

In this post, we’ll discuss some tips to identify what’s causing high CPU usage for your ASP.NET web applications.

There are a lot of reasons that your IIS worker process (w3wp.exe) could be using a lot of CPU. We’ll cover some of the top reasons and how to troubleshoot IIS performance problems.

To start, you should look at which web requests are currently executing with IIS to see if that helps you identify the issue to be able to troubleshoot IIS worker process.

How to View Running Web Requests in IIS

One of the first things you should do is see which web requests are currently executing. This may help you identify a specific URL that is causing the problem.

There’s a chance that you could recognize one of the URLs that’s known to take a very long time or cause high CPU issues.

Although, this may also show a bunch of web requests that are queued up and not directly lead you to the root cause.

Via the IIS User Interface

Via the IIS management console, you can view the running worker processes. You can view which IIS application pool is causing high CPU and view the currently running web requests.

iis manager click worker processes

After selecting “Worker Processes” from the main IIS menu, you can see the currently running IIS worker processes.

After selecting "Worker Processes" from the main IIS menu, you can see the currently running IIS worker processes.

If you double-click on a worker process, you can see all of the currently executing requests.

Here’s an example from one of our servers. You can see that each request is in different parts of the ASP.NET pipeline and currently executing different HTTP modules.

You can see that each request is in different parts of the ASP.NET pipeline and currently executing different HTTP modules.

Via Command Line

The appcmd.exe utility can be useful for a lot of things, including the currently running web requests.

C:WindowsSystem32inetsrv>appcmd list requests
REQUEST "f20000048000021c" (url:GET /nopcommerce, time:6312 msec, client:localhost, stage:BeginRequest, module:IIS Web Core)

Understanding The Results & Things to Look For

You can view the currently executing web requests via the IIS user interface or command line. Either way, it returns the same information.

  • URL: the complete URL that was being executed.
  • Time: the total amount of time, in milliseconds, the web request has been executing.
  • Client: the address of the user that initiated the request.
  • Stage: the stage of the IIS pipeline that the request is currently in.
  • Module: the ASP.NET module that is currently executing.

There are a few things you want to pay attention to when looking at the requests.

  • Are all of the requests for the same URL? Perhaps that URL is the source of the problem
  • Is a high number of requests coming from the same client? Perhaps a specific user is slamming your web server with traffic.
  • Are all the requests stuck in the same stage or module? There could be a problem with requests getting hung in that specific step of the IIS pipeline.

6 Common Causes and how to troubleshoot IIS Worker Process High CPU

There are a lot of reasons that you can be seeing w3wp.exe IIS Worker Process high CPU usage. I have selected six common causes to cover in this post:

  • High error rates within your ASP.NET web application.
  • Increase in web traffic causing high CPU.
  • Problems with application dependencies.
  • Garbage collection.
  • Requests getting blocked or hung somewhere in the ASP.NET pipeline.
  • Inefficient .NET code that needs to be optimized.

 1. High Error Rates Within Your ASP.NET Web Application

Application errors could be happening in your application, and you don’t even know it. Some errors will cause your users to receive an error message of some form. Other errors may happen, and nobody knows about it.

If you are using an error monitoring or application performance management tool, be sure to check those for high error rates.

There are a few places you can look for application error rates and actual errors, including Windows Event Viewer, IIS Logs, and more. Read this article to learn more: IIS Logs, Error Logs and More – 6 Ways to Find Failed ASP.NET Requests

Windows Performance Counters for Error Rates

There are two specific performance counters I would recommend reviewing for high error rates. You can check these by opening Performance Monitor within Windows and adding the counters to the chart view.

  • .NET CLR Exceptions -> # of Exceps Thrown / sec: Check this to see if a lot of exceptions are being thrown by your application. It is possible for your application to have a lot of hidden errors that can cause big performance problems.  Any exceptions at all are bad, but some are unavoidable.
  • W3SVC_W3WP -> % 500 HTTP Response Sent:  Any requests with a 500 status code are internal server errors. Make sure this percentage is very low. It should be 0-1%.

2. Increase in Web Traffic Causing IIS Worker Process High CPU

One of the simplest explanations for w3wp.exe high CPU usage is an increase in web traffic. However, if you don’t have any baseline for what your normal volume of traffic is, it can be hard to know if traffic has increased.

If you are using some application monitoring tool that tracks the traffic, be sure to check it and see if traffic levels have changed.

If you don’t have any way to know if traffic levels have changed, you could use your IIS log files to try and find out.

You can use VisualLogParser or Log Parser Lizard to query them.

Related tutorials:
Analyze your IIS Log Files – Favorite Log Parser Queries (VisualLogParser)
Tutorial for Log Parser Lizard GUI

There are also windows performance counters for Requests / Sec and Requests Current to see the current traffic rates in real time.

Possible Reasons for Higher Web Traffic

If traffic levels are up, you should evaluate if it should be or not. Here some things to think about in regards to increased traffic levels:

  • Client or user: Is there a huge spike in traffic from a specific client, user, or source? Perhaps something that accesses your site is not working correctly. You may need to block a specific IP address.
  • Bots: Similar to a specific user causing a lot of traffic, it could be a bot causing it. Look at the user agents being used to access your site in your IIS logs.
  • Oprah effect: Did Oprah or somebody mention your products? Did you just go viral? Getting a lot of attention is awesome, but you may need to scale up to handle it.

If your site is receiving a lot more traffic, you may need to get a bigger server (scale up) or more servers (scale out).

But if your site doesn’t get very many requests per second, traffic may not be the problem.

Many ASP.NET applications have 10-30 requests per second. However, I have also seen lightweight web requests on busy apps doing over 100 requests per second. 

The volume of traffic from one web app to another and the related CPU usage varies wildly. It’s all about your specific application.

How to Identify Expensive Web Requests

By identifying which web requests are taking the longest, you may be able to identify your high CPU issue or identify parts of your application that could use some performance review to improve.

Using an APM solution, like Retrace, can help you track performance over time of your entire application. It can also tell you which specific web requests take the longest.

APM tools use .NET profilers and other data collection techniques to understand the performance of your application down to the code level.

By identifying which web requests are taking the longest, you may be able to identify your high CPU issue or identify parts of your application that could use some performance review to improve.

Read more: Application Performance Management Solution with Retrace Code Profiling

3. Problems With Application Dependencies

Application Performance Problems

Today’s web applications leverage a lot of different types of external services and dependencies. Including SQL, NoSQL, queuing, caching, and many external HTTP web services.

Slowdowns from any application dependency can cause performance problems with your application.The most common problems are slow SQL queries or problems with external HTTP web services.

Tracking the performance of your application to this level requires an APM tool, like Retrace. Retrace tracks the performance of your application down to the code level. It can help you quickly identify slow SQL queries, web service calls, and much more.

4. Garbage Collection

Microsoft .NET utilizes garbage collection to manage the allocation and release of memory.

Depending on what your application does, the allocation and cleanup of application memory can cause a lot of garbage collection activity. For example, the usage of lots of large string variables on the large object heap causes garbage collection problems.

To measure if garbage collection could be causing problems for your application, check this Windows Performance Counter:

.NET CLR Memory -> % Time in GC: This counter reflects what % of the time your application spends doing garbage collection. If this number spikes a lot above 5-10%, you want to investigate memory usage further.

Garbage collection also has two modes. You may need to enable server mode, which is not the default.

5. Requests Are Getting Blocked and Hang in the ASP.NET Pipeline

Requests Are Getting Blocked and Hang in the ASP.NET Pipeline
ASP.NET Lifecycle

There are many steps in the lifecycle of an ASP.NET request. This includes basic steps like the start of the request, authentication, authorization, evaluating the correct HTTP handler and finishing the request. As part of this, there are many standard and custom HTTP modules that may be in use.

The first thing I showed you was how to view the currently executing web requests.

If you are having performance problems, I would suggest looking to see if all the requests seem to hang on a specific HTTP module.

HTTP modules can be native code or managed .NET code. They can be standard .NET modules like FormsAuthenticaion or SessionStateModule. Many applications also use 3rd party or custom HTTP modules.

Are You Using Sessions?

Most people don’t realize how much of a performance overhead ASP.NET sessions cause.

On every page load, they cause your IIS worker process to retrieve your session object, lock it, and then release it at the end of the request.

Sessions cause locking and can cause a bottleneck within your application.

If you are using a session provider like Redis or SQL, any performance slowdowns will impact the performance of your application.

6. Inefficient .NET Code That Needs to Be Optimized

If none of the other common causes was a problem, you might need to dig into the code to make improvements. You will need to use .NET code profilers to capture what methods are being called in your code and how long they take.

Profilers can help you identify specific methods in your code that are very slow.

Warning: Profilers do add overhead to your application. So if your application already has very high CPU usage (90+%), profiling will be very slow, and the performance of your application will get worse.

This could make your application unusable even depending on the detail level of profiling you are doing and the CPU usage before you started profiling.

My favorite .NET profiler is RedGate’s ANTS Performance Profiler. They do offer a free trial that you can take advantage of.

RedGate's ANTS Performance Profiler.

Check out these articles to learn more about ANTS and how to profile ASP.NET applications.

How to Troubleshoot High .NET App CPU in Production With ANTS and Process Hacker
Walkthrough: ASP.NET profiling with ANTS Performance Profiler

Good Luck With Your IIS Performance Problems!

Hopefully, you are reading this because you are trying to figure out how to improve performance. I hope your server isn’t at 100% and you are scrambling!

As a provider of APM solutions, we spend a lot of time working on and thinking about application performance problems. We hope this guide has been helpful to troubleshoot IIS Worker Process (w3wp.exe).